内存测试工具mbw分析

本文记录mbw测试原理及代码分析
1、mbw下载地址:
      包含文件Makefile  mbw  mbw.1  mbw.c  mbw.spec
 2、mbw代码分析
 

/* mbw.c源码格函数解析*/
   /* 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;
  //calloc是一个ISO C函数函数名: calloc函数原型:void *calloc(size_t n, size_t size);功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
    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型元素个数
 * long_size: sizeof(long) cached //long型内存大小,即占几个字节 
 * 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; //timeval结构体定义在time.h中,具体解析http://blog.csdn.net/yusiguyuan/article/details/21781839
    double te;
    unsigned int long_size=sizeof(long);
    /* array size in bytes */
    unsigned long long array_bytes=asize*long_size;

if(type==1) { /* memcpy test */
        /* timer starts */
        gettimeofday(&starttime, NULL);//记录开始时间
        memcpy(b, a, array_bytes);//拷贝array_bytes大小 内存
        /* timer stops */
        gettimeofday(&endtime, NULL);//记录结束时间
    } else if(type==2) { /* memcpy block test */
        gettimeofday(&starttime, NULL);
        for(t=0; t<array_bytes; t+=block_size) {//每次按照block_size 大小逐次拷贝
            b=mempcpy(b, a, block_size);
     //void *memccpy(void *dest, const void *src, int c, size_t n);在两块不重叠的内存地址间复制内容,直至复制了n字节或遇到内容为c的字节
        }
        if(t>array_bytes) {
            b=mempcpy(b, a, t-array_bytes);
        }
        gettimeofday(&endtime, NULL);
    } else { /* 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 0:
            printf("Method: MEMCPY\t");
            break;
        case 1:
            printf("Method: DUMB\t");
            break;
        case 2:
            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(0>testno) {
                    printf("Error: test number must be between 0 and %d\n", MAX_TESTS);
                    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(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);
    }

/* run all tests requested, the proper number of times */
    for(testno=0; testno<MAX_TESTS; testno++) {
        te_sum=0;
        if(tests[testno]) {
            for (i=0; i<nr_loops; i++) {
                te=worker(asize, a, b, testno, block_size);
                te_sum+=te;
                printf("%d\t", i);
                printout(te, mt, testno);
            }
            if(showavg) {
                printf("AVG\t");
                printout(te_sum/nr_loops, mt, testno);
            }
        }
    }

free(a);
    free(b);
    return 0;
}

 

posted @ 2015-07-30 22:41  ShaneZhou  阅读(2020)  评论(1编辑  收藏  举报