/*
* vim: ai ts=4 sts=4 sw=4 cinoptions=>4 expandtab
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
/* how many runs to average by default */
#define DEFAULT_NR_LOOPS 10
/* we have 3 tests at the moment */
#define MAX_TESTS 3
/* default block size for test 2, in bytes */
#define DEFAULT_BLOCK_SIZE 262144
/* test types */
#define TEST_MEMCPY 0
#define TEST_DUMB 1
#define TEST_MCBLOCK 2
/* version number */
#define VERSION "1.4"
/*
* MBW memory bandwidth benchmark
*
* 2006, 2012 [email protected]
* 2013 [email protected]
* (Special thanks to Stephen Pasich)
*
* http://github.com/raas/mbw
*
* compile with:
* gcc -O -o mbw mbw.c
*
* run with eg.:
*
* ./mbw 300
*
* or './mbw -h' for help
*
* watch out for swap usage (or turn off swap)
*/
void usage()
{
printf("mbw memory benchmark v%s, https://github.com/raas/mbw\n", VERSION);
printf("Usage: mbw [options] array_size_in_MiB\n");
printf("Options:\n");
printf(" -n: number of runs per test (0 to run forever)\n");
printf(" -a: Don't display average\n");
printf(" -t%d: memcpy test\n", TEST_MEMCPY);
printf(" -t%d: dumb (b[i]=a[i] style) test\n", TEST_DUMB);
printf(" -t%d: memcpy test with fixed block size\n", TEST_MCBLOCK);
printf(" -b <size>: block size in bytes for -t2 (default: %d)\n", DEFAULT_BLOCK_SIZE);
printf(" -q: quiet (print statistics only)\n");
printf("(will then use two arrays, watch out for swapping)\n");
printf("'Bandwidth' is amount of data copied over the time this operation took.\n");
printf("\nThe default is to run all tests available.\n");
}
/* ------------------------------------------------------ */
/* allocate a test array and fill it with data
* so as to force Linux to _really_ allocate it */
long *make_array(unsigned long long asize)
{
unsigned long long t;
unsigned int long_size=sizeof(long);
long *a;
a=calloc(asize, long_size);
if(NULL==a) {
perror("Error allocating memory");
exit(1);
}
/* make sure both arrays are allocated, fill with pattern */
for(t=0; t<asize; t++) {
a[t]=0xaa;
}
return a;
}
/* actual benchmark */
/* asize: number of type 'long' elements in test arrays
* long_size: sizeof(long) cached
* type: 0=use memcpy, 1=use dumb copy loop (whatever GCC thinks best)
*
* return value: elapsed time in seconds
*/
double worker(unsigned long long asize, long *a, long *b, int type, unsigned long long block_size)
{
unsigned long long t;
struct timeval starttime, endtime;
double te;
unsigned int long_size=sizeof(long);
/* array size in bytes */
unsigned long long array_bytes=asize*long_size;
if(type==TEST_MEMCPY) { /* memcpy test */
/* timer starts */
gettimeofday(&starttime, NULL);
memcpy(b, a, array_bytes);
/* timer stops */
gettimeofday(&endtime, NULL);
} else if(type==TEST_MCBLOCK) { /* memcpy block test */
char* aa = (char*)a;
char* bb = (char*)b;
gettimeofday(&starttime, NULL);
for (t=array_bytes; t >= block_size; t-=block_size, aa+=block_size){
bb=(char *) memcpy(bb, aa, block_size) + block_size;
}
if(t) {
bb=(char *) memcpy(bb, aa, t) + t;
}
gettimeofday(&endtime, NULL);
} else if(type==TEST_DUMB) { /* dumb test */
gettimeofday(&starttime, NULL);
for(t=0; t<asize; t++) {
b[t]=a[t];
}
gettimeofday(&endtime, NULL);
}
te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
return te;
}
/* ------------------------------------------------------ */
/* pretty print worker's output in human-readable terms */
/* te: elapsed time in seconds
* mt: amount of transferred data in MiB
* type: see 'worker' above
*
* return value: -
*/
void printout(double te, double mt, int type)
{
switch(type) {
case TEST_MEMCPY:
printf("Method: MEMCPY\t");
break;
case TEST_DUMB:
printf("Method: DUMB\t");
break;
case TEST_MCBLOCK:
printf("Method: MCBLOCK\t");
break;
}
printf("Elapsed: %.5f\t", te);
printf("MiB: %.5f\t", mt);
printf("Copy: %.3f MiB/s\n", mt/te);
return;
}
/* ------------------------------------------------------ */
int main(int argc, char **argv)
{
unsigned int long_size=0;
double te, te_sum; /* time elapsed */
unsigned long long asize=0; /* array size (elements in array) */
int i;
long *a, *b; /* the two arrays to be copied from/to */
int o; /* getopt options */
unsigned long testno;
/* options */
/* how many runs to average? */
int nr_loops=DEFAULT_NR_LOOPS;
/* fixed memcpy block size for -t2 */
unsigned long long block_size=DEFAULT_BLOCK_SIZE;
/* show average, -a */
int showavg=1;
/* what tests to run (-t x) */
int tests[MAX_TESTS];
double mt=0; /* MiBytes transferred == array size in MiB */
int quiet=0; /* suppress extra messages */
tests[0]=0;
tests[1]=0;
tests[2]=0;
while((o=getopt(argc, argv, "haqn:t:b:")) != EOF) {
switch(o) {
case 'h':
usage();
exit(1);
break;
case 'a': /* suppress printing average */
showavg=0;
break;
case 'n': /* no. loops */
nr_loops=strtoul(optarg, (char **)NULL, 10);
break;
case 't': /* test to run */
testno=strtoul(optarg, (char **)NULL, 10);
if(testno>MAX_TESTS-1) {
printf("Error: test number must be between 0 and %d\n", MAX_TESTS-1);
exit(1);
}
tests[testno]=1;
break;
case 'b': /* block size in bytes*/
block_size=strtoull(optarg, (char **)NULL, 10);
if(0>=block_size) {
printf("Error: what block size do you mean?\n");
exit(1);
}
break;
case 'q': /* quiet */
quiet=1;
break;
default:
break;
}
}
/* default is to run all tests if no specific tests were requested */
if( (tests[0]+tests[1]+tests[2]) == 0) {
tests[0]=1;
tests[1]=1;
tests[2]=1;
}
if( nr_loops==0 && ((tests[0]+tests[1]+tests[2]) != 1) ) {
printf("Error: nr_loops can be zero if only one test selected!\n");
exit(1);
}
if(optind<argc) {
mt=strtoul(argv[optind++], (char **)NULL, 10);
} else {
printf("Error: no array size given!\n");
exit(1);
}
if(0>=mt) {
printf("Error: array size wrong!\n");
exit(1);
}
/* ------------------------------------------------------ */
long_size=sizeof(long); /* the size of long on this platform */
asize=1024*1024/long_size*mt; /* how many longs then in one array? */
if(asize*long_size < block_size) {
printf("Error: array size larger than block size (%llu bytes)!\n", block_size);
exit(1);
}
if(!quiet) {
printf("Long uses %d bytes. ", long_size);
printf("Allocating 2*%lld elements = %lld bytes of memory.\n", asize, 2*asize*long_size);
if(tests[2]) {
printf("Using %lld bytes as blocks for memcpy block copy test.\n", block_size);
}
}
a=make_array(asize);
b=make_array(asize);
/* ------------------------------------------------------ */
if(!quiet) {
printf("Getting down to business... Doing %d runs per test.\n", nr_loops);
}
/* ru

Free飝Fly
- 粉丝: 5181
最新资源
- 基于单片机的智能火灾报警系统大学本科方案设计书37184.doc
- 基于区块链技术的国内企业征信系统改进研究.docx
- 深度学习循环神经网络.ppt
- 数据库原理课程设计研究报告模板.doc
- 送料小车自动往返的PLC控制.ppt
- 单片机大学课程方案设计多功能定时器.doc
- 大数据环境下隐私顾虑影响因素探讨.docx
- ××公司一体化市场物流咨询项目信息化规划建议讨论稿普通汽车服务信息化规划建议(分报告七).ppt
- T3073无线传感器网络中数据收集器移动的路由协议的分析研究2.doc
- 圆柱形锌空气电池产业化项目管理技术总结.doc
- 物联网发电厂设备仓储管理系统.docx
- 大数据下的设计.docx
- 【项目经理培训】-IT行业软件项目经理培训.doc
- 大数据时代独立学院数据库课程体系的改革.docx
- PLC控制系统的设计.ppt
- 从智能语音助手角度浅析计算机智能科学与技术对电子设备交互的作用.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


