micro_bench.c revision b56034796a7cadee89c4cd5e3c0f0730193231de
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
406ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic int do_sleep(int delay) {
416ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
426ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
436ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
446ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    while (1) {
456ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
466ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        sleep(delay);
476ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
486ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
496ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
506ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
516ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        printf("sleep(%d) took %ld.%06ld seconds\n", delay, tv2.tv_sec, tv2.tv_usec);
526ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
536ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
546ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
556ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
566ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
576ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellyint cpu_foo;
586ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
596ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic int do_cpu(int a) {
606ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
616ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
626ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
636ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    while (1) {
646ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
656ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        for (cpu_foo = 0; cpu_foo < 100000000; cpu_foo++);
666ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
676ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
686ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
696ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
706ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        printf("cpu took %ld.%06ld seconds\n", tv2.tv_sec, tv2.tv_usec);
716ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
726ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
736ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
746ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
756ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic double mb_sec(unsigned long bytes, struct timeval *delta) {
766ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    unsigned long us = delta->tv_sec * 1000000 + delta->tv_usec;
776ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return (double)bytes * 1000000.0 / 1048576.0 / (double)us;
786ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
796ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
806ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic int do_memset(int sz) {
816ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
826ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
836ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int i;
846ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
856ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    uint8_t *b = malloc(sz);
866ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!b) return -1;
876ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int c = 1000000000/sz;
886ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
896ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    while (1) {
906ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
916ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        for (i = 0; i < c; i++)
926ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            memset(b, 0, sz);
936ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
946ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
956ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
966ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
976ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
986ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        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));
996ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1006ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
1016ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1026ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1036ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic int do_memcpy(int sz) {
1046ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
1056ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
1066ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int i;
1076ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1086ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    uint8_t *a = malloc(sz);
1096ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!a) return -1;
1106ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    uint8_t *b = malloc(sz);
1116ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!b) return -1;
1126ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int c = 1000000000/sz;
1136ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1146ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    while (1) {
1156ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
1166ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        for (i = 0; i < c; i++)
1176ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            memcpy(b, a, sz);
1186ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1196ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
1206ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1216ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
1226ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1236ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        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));
1246ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1256ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
1266ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1276ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1286ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellyint foo;
1296ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1306ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic int do_memread(int sz) {
1316ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv1;
1326ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    struct timeval tv2;
1336ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int i, j;
1346ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1356ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int *b = malloc(sz);
1366ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (!b) return -1;
1376ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int c = 1000000000/sz;
1386ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1396ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    while (1) {
1406ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv1, NULL);
1416ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        for (i = 0; i < c; i++)
1426ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            for (j = 0; j < sz/4; j++)
1436ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly                foo = b[j];
1446ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1456ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        gettimeofday(&tv2, NULL);
1466ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1476ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        tv_sub(&tv2, &tv1);
1486ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1496ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        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));
1506ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1516ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return 0;
1526ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1536ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1546ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystruct {
1556ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    char *name;
1566ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int (*ptr)(int);
1576ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly} function_table[]  = {
1586ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"sleep", do_sleep},
1596ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"cpu", do_cpu},
1606ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"memset", do_memset},
1616ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"memcpy", do_memcpy},
1626ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {"memread", do_memread},
1636ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    {NULL, NULL},
1646ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly};
1656ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1666ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellystatic void usage() {
1676ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int i;
1686ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1696ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    printf("Usage:\n");
1706ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    for (i = 0; function_table[i].name; i++) {
1716ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        printf("\tmicro_bench %s ARG\n", function_table[i].name);
1726ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1736ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
1746ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1756ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pellyint main(int argc, char **argv) {
1766ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    int i;
1776ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly
1786ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    if (argc != 3) {
1796ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        usage();
1806ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        return -1;
1816ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1826ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    for (i = 0; function_table[i].name; i++) {
1836ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        if (!strcmp(argv[1], function_table[i].name)) {
1846ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            printf("%s\n", function_table[i].name);
1856ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly            return (*function_table[i].ptr)(atoi(argv[2]));
1866ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly        }
1876ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    }
1886ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    usage();
1896ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly    return -1;
1906ca26ef8a78cc46dd8c779dcd7c611a247dd22c7Nick Pelly}
191