• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
tv_sub(struct timeval * tv2,struct timeval * tv1)31 static 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 
do_sleep(int iters,int delay)40 static int do_sleep(int iters, int delay) {
41     struct timeval tv1;
42     struct timeval tv2;
43     int i;
44 
45     for (i = 0; iters == -1 || i < iters; i++) {
46         gettimeofday(&tv1, NULL);
47         sleep(delay);
48         gettimeofday(&tv2, NULL);
49 
50         tv_sub(&tv2, &tv1);
51 
52         printf("sleep(%d) took %ld.%06ld seconds\n", delay, tv2.tv_sec, tv2.tv_usec);
53     }
54 
55     return 0;
56 }
57 
58 int cpu_foo;
59 
do_cpu(int iters,int a)60 static int do_cpu(int iters, int a) {
61     struct timeval tv1;
62     struct timeval tv2;
63     int i;
64 
65     for (i = 0; iters == -1 || i < iters; i++) {
66         gettimeofday(&tv1, NULL);
67         for (cpu_foo = 0; cpu_foo < 100000000; cpu_foo++);
68         gettimeofday(&tv2, NULL);
69 
70         tv_sub(&tv2, &tv1);
71 
72         printf("cpu took %ld.%06ld seconds\n", tv2.tv_sec, tv2.tv_usec);
73     }
74     return 0;
75 }
76 
mb_sec(unsigned long bytes,struct timeval * delta)77 static double mb_sec(unsigned long bytes, struct timeval *delta) {
78     unsigned long us = delta->tv_sec * 1000000 + delta->tv_usec;
79     return (double)bytes * 1000000.0 / 1048576.0 / (double)us;
80 }
81 
do_memset(int iters,int sz)82 static int do_memset(int iters, int sz) {
83     struct timeval tv1;
84     struct timeval tv2;
85     int i, j;
86 
87     uint8_t *b = malloc(sz);
88     if (!b) return -1;
89     int c = 1000000000/sz;
90 
91     for (i = 0; iters == -1 || i < iters; i++) {
92         gettimeofday(&tv1, NULL);
93         for (j = 0; j < c; j++)
94             memset(b, 0, sz);
95 
96         gettimeofday(&tv2, NULL);
97 
98         tv_sub(&tv2, &tv1);
99 
100         printf("memset %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n",
101                 c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2));
102     }
103     return 0;
104 }
105 
do_memcpy(int iters,int sz)106 static int do_memcpy(int iters, int sz) {
107     struct timeval tv1;
108     struct timeval tv2;
109     int i, j;
110 
111     uint8_t *a = malloc(sz);
112     if (!a) return -1;
113     uint8_t *b = malloc(sz);
114     if (!b) return -1;
115     int c = 1000000000/sz;
116 
117     for (i = 0; iters == -1 || i < iters; i++) {
118         gettimeofday(&tv1, NULL);
119         for (j = 0; j < c; j++)
120             memcpy(b, a, sz);
121 
122         gettimeofday(&tv2, NULL);
123 
124         tv_sub(&tv2, &tv1);
125 
126         printf("memcpy %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n",
127                 c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2));
128     }
129     return 0;
130 }
131 
132 int foo;
133 
do_memread(int iters,int sz)134 static int do_memread(int iters, int sz) {
135     struct timeval tv1;
136     struct timeval tv2;
137     int i, j, k;
138 
139     int *b = malloc(sz);
140     if (!b) return -1;
141     int c = 1000000000/sz;
142 
143     for (i = 0; iters == -1 || i < iters; i++) {
144         gettimeofday(&tv1, NULL);
145         for (j = 0; j < c; j++)
146             for (k = 0; k < sz/4; k++)
147                 foo = b[k];
148 
149         gettimeofday(&tv2, NULL);
150 
151         tv_sub(&tv2, &tv1);
152 
153         printf("read %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n",
154                 c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2));
155     }
156     return 0;
157 }
158 
159 struct {
160     char *name;
161     int (*ptr)(int, int);
162 } function_table[]  = {
163     {"sleep", do_sleep},
164     {"cpu", do_cpu},
165     {"memset", do_memset},
166     {"memcpy", do_memcpy},
167     {"memread", do_memread},
168     {NULL, NULL},
169 };
170 
usage()171 static void usage() {
172     int i;
173 
174     printf("Usage:\n");
175     for (i = 0; function_table[i].name; i++) {
176         printf("\tmicro_bench %s ARG [ITERS]\n", function_table[i].name);
177     }
178 }
179 
main(int argc,char ** argv)180 int main(int argc, char **argv) {
181     int i;
182     int iters;
183 
184     if (argc < 3 || argc > 4) {
185         usage();
186         return -1;
187     }
188     if (argc == 3) {
189         iters = -1;
190     } else {
191         iters = atoi(argv[3]);
192     }
193     for (i = 0; function_table[i].name; i++) {
194         if (!strcmp(argv[1], function_table[i].name)) {
195             printf("%s\n", function_table[i].name);
196             return (*function_table[i].ptr)(iters, atoi(argv[2]));
197         }
198     }
199     usage();
200     return -1;
201 }
202