1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* This program tries to benchmark stdio operations like fread() and 30 * fwrite() with various chunk sizes. We always read/write from /dev/zero 31 * to ensure that disk speed and caching don't change our results. 32 * 33 * We really do this to measure improvements in the low-level stdio 34 * features. 35 */ 36 37 #include <stdio.h> 38 #include <time.h> 39 #include <string.h> 40 #include <errno.h> 41 42 static char buffer[1024*1024]; 43 44 /* Return current time in milli-seconds, as a double */ 45 static double 46 now_ms(void) 47 { 48 struct timespec ts; 49 clock_gettime(CLOCK_MONOTONIC, &ts); 50 return ts.tv_sec*1000. + ts.tv_nsec*1e-6; 51 } 52 53 void read_file(FILE* fp, int chunkSize) 54 { 55 int totalSize = sizeof(buffer); 56 for ( ; totalSize > 0; totalSize -= chunkSize) { 57 fread(buffer, 1, chunkSize, fp); 58 } 59 } 60 61 void write_file(FILE* fp, int chunkSize) 62 { 63 int totalSize = sizeof(buffer); 64 for ( ; totalSize > 0; totalSize -= chunkSize) { 65 fwrite(buffer, 1, chunkSize, fp); 66 } 67 } 68 69 #define BENCH(op,...) \ 70 do { \ 71 double time_ms = now_ms(); \ 72 op ; \ 73 time_ms = now_ms() - time_ms; \ 74 double bandwidth = sizeof(buffer)*1000./1024./time_ms; \ 75 printf("bench %-30s %8.2f ms (%.1f KB/s) \n", #op, time_ms, bandwidth ); \ 76 } while (0) 77 78 int main(void) 79 { 80 FILE* fp = fopen("/dev/zero", "rw"); 81 82 if (fp == NULL) { 83 fprintf(stderr,"Could not open /dev/zero: %s\n", strerror(errno)); 84 return 1; 85 } 86 87 BENCH(read_file(fp,1)); 88 BENCH(read_file(fp,2)); 89 BENCH(read_file(fp,3)); 90 BENCH(read_file(fp,4)); 91 BENCH(read_file(fp,8)); 92 BENCH(read_file(fp,16)); 93 BENCH(read_file(fp,32)); 94 BENCH(read_file(fp,64)); 95 BENCH(read_file(fp,256)); 96 BENCH(read_file(fp,1024)); 97 BENCH(read_file(fp,4096)); 98 BENCH(read_file(fp,16384)); 99 BENCH(read_file(fp,65536)); 100 101 BENCH(write_file(fp,1)); 102 BENCH(write_file(fp,2)); 103 BENCH(write_file(fp,3)); 104 BENCH(write_file(fp,4)); 105 BENCH(write_file(fp,8)); 106 BENCH(write_file(fp,16)); 107 BENCH(write_file(fp,32)); 108 BENCH(write_file(fp,64)); 109 BENCH(write_file(fp,256)); 110 BENCH(write_file(fp,1024)); 111 BENCH(write_file(fp,4096)); 112 BENCH(write_file(fp,16384)); 113 BENCH(write_file(fp,65536)); 114 115 fclose(fp); 116 return 0; 117 } 118