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