Home | History | Annotate | Download | only in micro_bench
      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 */
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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