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