16ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly/*
26ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** Copyright 2010 The Android Open Source Project
36ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly**
46ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** Licensed under the Apache License, Version 2.0 (the "License");
56ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** you may not use this file except in compliance with the License.
66ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** You may obtain a copy of the License at
76ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly**
86ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly**     http://www.apache.org/licenses/LICENSE-2.0
96ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly**
106ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** Unless required by applicable law or agreed to in writing, software
116ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** distributed under the License is distributed on an "AS IS" BASIS,
126ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** See the License for the specific language governing permissions and
146ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly** limitations under the License.
156ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly*/
166ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
176ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly/*
186ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly * Some quick and dirty micro-benchmarks
196ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly */
206ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
216ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly#include <stdlib.h>
226ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly#include <stdio.h>
236ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly#include <errno.h>
246ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly#include <sys/uio.h>
256ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly#include <unistd.h>
266ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly#include <sys/time.h>
27b56034796a7cadee89c4cd5e3c0f0730193231deOlivier Bailly#include <stdint.h>
28b56034796a7cadee89c4cd5e3c0f0730193231deOlivier Bailly#include <string.h>
296ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
306ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly/* tv2 -= tv1 */
316ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic void tv_sub(struct timeval *tv2, struct timeval *tv1) {
326ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv2->tv_sec -= tv1->tv_sec;
336ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv2->tv_usec -= tv1->tv_usec;
346ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        while (tv2->tv_usec < 0) {
356ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            tv2->tv_usec += 1000000;
366ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            tv2->tv_sec -= 1;
376ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        }
386ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
396ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
40192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowestatic int do_sleep(int iters, int delay) {
416ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
426ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
43192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    int i;
446ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
45192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    for (i = 0; iters == -1 || i < iters; i++) {
466ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
476ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        sleep(delay);
486ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
496ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
506ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
516ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
526ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        printf("sleep(%d) took %ld.%06ld seconds\n", delay, tv2.tv_sec, tv2.tv_usec);
536ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
546ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
556ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
566ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
576ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
586ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellyint cpu_foo;
596ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
60192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowestatic int do_cpu(int iters, int a) {
616ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
626ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
63192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    int i;
646ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
65192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    for (i = 0; iters == -1 || i < iters; i++) {
666ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
676ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        for (cpu_foo = 0; cpu_foo < 100000000; cpu_foo++);
686ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
696ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
706ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
716ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
726ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        printf("cpu took %ld.%06ld seconds\n", tv2.tv_sec, tv2.tv_usec);
736ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
746ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
756ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
766ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
776ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic double mb_sec(unsigned long bytes, struct timeval *delta) {
786ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    unsigned long us = delta->tv_sec * 1000000 + delta->tv_usec;
796ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return (double)bytes * 1000000.0 / 1048576.0 / (double)us;
806ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
816ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
82192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowestatic int do_memset(int iters, int sz) {
836ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
846ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
85192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    int i, j;
866ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
876ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    uint8_t *b = malloc(sz);
886ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!b) return -1;
896ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int c = 1000000000/sz;
906ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
91192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    for (i = 0; iters == -1 || i < iters; i++) {
926ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
93192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        for (j = 0; j < c; j++)
946ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            memset(b, 0, sz);
956ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
966ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
976ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
986ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
996ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
100192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        printf("memset %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n",
101192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe                c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2));
1026ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1036ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
1046ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1056ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
106192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowestatic int do_memcpy(int iters, int sz) {
1076ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
1086ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
109192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    int i, j;
1106ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1116ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    uint8_t *a = malloc(sz);
1126ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!a) return -1;
1136ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    uint8_t *b = malloc(sz);
1146ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!b) return -1;
1156ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int c = 1000000000/sz;
1166ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
117192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    for (i = 0; iters == -1 || i < iters; i++) {
1186ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
119192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        for (j = 0; j < c; j++)
1206ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            memcpy(b, a, sz);
1216ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1226ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
1236ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1246ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
1256ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
126192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        printf("memcpy %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n",
127192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe                c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2));
1286ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1296ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
1306ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1316ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1326ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellyint foo;
1336ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
134192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowestatic int do_memread(int iters, int sz) {
1356ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
1366ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
137192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    int i, j, k;
1386ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1396ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int *b = malloc(sz);
1406ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!b) return -1;
1416ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int c = 1000000000/sz;
1426ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
143192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    for (i = 0; iters == -1 || i < iters; i++) {
1446ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
145192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        for (j = 0; j < c; j++)
146192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe            for (k = 0; k < sz/4; k++)
147192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe                foo = b[k];
1486ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1496ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
1506ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1516ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
1526ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
153192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        printf("read %dx%d bytes took %ld.%06ld seconds (%f MB/s)\n",
154192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe                c, sz, tv2.tv_sec, tv2.tv_usec, mb_sec(c*sz, &tv2));
1556ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1566ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
1576ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1586ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1596ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystruct {
1606ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    char *name;
161192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    int (*ptr)(int, int);
1626ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly} function_table[]  = {
1636ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"sleep", do_sleep},
1646ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"cpu", do_cpu},
1656ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"memset", do_memset},
1666ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"memcpy", do_memcpy},
1676ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"memread", do_memread},
1686ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {NULL, NULL},
1696ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly};
1706ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1716ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic void usage() {
1726ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int i;
1736ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1746ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    printf("Usage:\n");
1756ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    for (i = 0; function_table[i].name; i++) {
176192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        printf("\tmicro_bench %s ARG [ITERS]\n", function_table[i].name);
1776ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1786ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1796ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1806ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellyint main(int argc, char **argv) {
1816ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int i;
182192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    int iters;
1836ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
184192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    if (argc < 3 || argc > 4) {
1856ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        usage();
1866ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        return -1;
1876ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
188192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    if (argc == 3) {
189192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        iters = -1;
190192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    } else {
191192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe        iters = atoi(argv[3]);
192192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe    }
1936ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    for (i = 0; function_table[i].name; i++) {
1946ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        if (!strcmp(argv[1], function_table[i].name)) {
1956ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            printf("%s\n", function_table[i].name);
196192c72580b4a3a1ff527ba433dbcd5c080fbd218Eric Rowe            return (*function_table[i].ptr)(iters, atoi(argv[2]));
1976ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        }
1986ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1996ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    usage();
2006ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return -1;
2016ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
202