micro_bench.c revision b56034796a7cadee89c4cd5e3c0f0730193231de
1/* 2** Copyright 2010 The Android Open Source Project 3** 4** Licensed under the Apache License, Version 2.0 (the "License"); 5** you may not use this file except in compliance with the License. 6** You may obtain a copy of the License at 7** 8** http://www.apache.org/licenses/LICENSE-2.0 9** 10** Unless required by applicable law or agreed to in writing, software 11** distributed under the License is distributed on an "AS IS" BASIS, 12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13** See the License for the specific language governing permissions and 14** limitations under the License. 15*/ 16 17/* 18 * Some quick and dirty micro-benchmarks 19 */ 20 21#include <stdlib.h> 22#include <stdio.h> 23#include <errno.h> 24#include <sys/uio.h> 25#include <unistd.h> 26#include <sys/time.h> 27#include <stdint.h> 28#include <string.h> 29 30/* tv2 -= tv1 */ 31static void tv_sub(struct timeval *tv2, struct timeval *tv1) { 32 tv2->tv_sec -= tv1->tv_sec; 33 tv2->tv_usec -= tv1->tv_usec; 34 while (tv2->tv_usec < 0) { 35 tv2->tv_usec += 1000000; 36 tv2->tv_sec -= 1; 37 } 38} 39 40static int do_sleep(int delay) { 41 struct timeval tv1; 42 struct timeval tv2; 43 44 while (1) { 45 gettimeofday(&tv1, NULL); 46 sleep(delay); 47 gettimeofday(&tv2, NULL); 48 49 tv_sub(&tv2, &tv1); 50 51 printf("sleep(%d) took %ld.%06ld seconds\n", delay, tv2.tv_sec, tv2.tv_usec); 52 } 53 54 return 0; 55} 56 57int cpu_foo; 58 59static int do_cpu(int a) { 60 struct timeval tv1; 61 struct timeval tv2; 62 63 while (1) { 64 gettimeofday(&tv1, NULL); 65 for (cpu_foo = 0; cpu_foo < 100000000; cpu_foo++); 66 gettimeofday(&tv2, NULL); 67 68 tv_sub(&tv2, &tv1); 69 70 printf("cpu took %ld.%06ld seconds\n", tv2.tv_sec, tv2.tv_usec); 71 } 72 return 0; 73} 74 75static double mb_sec(unsigned long bytes, struct timeval *delta) { 76 unsigned long us = delta->tv_sec * 1000000 + delta->tv_usec; 77 return (double)bytes * 1000000.0 / 1048576.0 / (double)us; 78} 79 80static int do_memset(int sz) { 81 struct timeval tv1; 82 struct timeval tv2; 83 int i; 84 85 uint8_t *b = malloc(sz); 86 if (!b) return -1; 87 int c = 1000000000/sz; 88 89 while (1) { 90 gettimeofday(&tv1, NULL); 91 for (i = 0; i < c; i++) 92 memset(b, 0, sz); 93 94 gettimeofday(&tv2, NULL); 95 96 tv_sub(&tv2, &tv1); 97 98 printf("memset %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n", c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2)); 99 } 100 return 0; 101} 102 103static int do_memcpy(int sz) { 104 struct timeval tv1; 105 struct timeval tv2; 106 int i; 107 108 uint8_t *a = malloc(sz); 109 if (!a) return -1; 110 uint8_t *b = malloc(sz); 111 if (!b) return -1; 112 int c = 1000000000/sz; 113 114 while (1) { 115 gettimeofday(&tv1, NULL); 116 for (i = 0; i < c; i++) 117 memcpy(b, a, sz); 118 119 gettimeofday(&tv2, NULL); 120 121 tv_sub(&tv2, &tv1); 122 123 printf("memcpy %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n", c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2)); 124 } 125 return 0; 126} 127 128int foo; 129 130static int do_memread(int sz) { 131 struct timeval tv1; 132 struct timeval tv2; 133 int i, j; 134 135 int *b = malloc(sz); 136 if (!b) return -1; 137 int c = 1000000000/sz; 138 139 while (1) { 140 gettimeofday(&tv1, NULL); 141 for (i = 0; i < c; i++) 142 for (j = 0; j < sz/4; j++) 143 foo = b[j]; 144 145 gettimeofday(&tv2, NULL); 146 147 tv_sub(&tv2, &tv1); 148 149 printf("read %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n", c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2)); 150 } 151 return 0; 152} 153 154struct { 155 char *name; 156 int (*ptr)(int); 157} function_table[] = { 158 {"sleep", do_sleep}, 159 {"cpu", do_cpu}, 160 {"memset", do_memset}, 161 {"memcpy", do_memcpy}, 162 {"memread", do_memread}, 163 {NULL, NULL}, 164}; 165 166static void usage() { 167 int i; 168 169 printf("Usage:\n"); 170 for (i = 0; function_table[i].name; i++) { 171 printf("\tmicro_bench %s ARG\n", function_table[i].name); 172 } 173} 174 175int main(int argc, char **argv) { 176 int i; 177 178 if (argc != 3) { 179 usage(); 180 return -1; 181 } 182 for (i = 0; function_table[i].name; i++) { 183 if (!strcmp(argv[1], function_table[i].name)) { 184 printf("%s\n", function_table[i].name); 185 return (*function_table[i].ptr)(atoi(argv[2])); 186 } 187 } 188 usage(); 189 return -1; 190} 191