一个简单的内存读写带宽测试程序

之前有写文章介绍了 mbw(https://blog.csdn.net/engrossment/article/details/88314722)以及 lmbench(https://blog.csdn.net/engrossment/article/details/83830363)。其中 mbw 的只是简单使用了 memcpy 系统调用进行测试,而 lmbench 里面的 bw_mem、stream 则给出了多种模式的带宽测试方式。查看其代码实现,比较复杂,而且加入了一些运算,使得在嵌入式的测试场景中,处理器成为了测试的瓶颈,无法测出更好的峰值。

于是参考 stream 的实现,简化了数据的读写,而且是读、写各自独立统计。代码如下。注意编译使用 -O3 优化级别编译。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>

//NOTE, you should compile this program with gcc -O3

#define N 10000000  // Count of array elements.

// Return seconds since Epoch.
double mysecond() {
    struct timeval tp;
    struct timezone tzp;
    gettimeofday(&tp, &tzp);
    return ((double)tp.tv_sec + (double)tp.tv_usec * 1.e-6 );
}

int main(int argc, char *argv[]) {
    int i, j;
    double t1, t2;
    double w_cost = 0;
    double r_cost = 0;
    volatile register double tmp;   // Set volatile in case GCC disable read.
    static double mem[N];           // Set static for larger array.

    printf("Test writing %ld MB data for 10 times...\n", N * sizeof(double) / 1024 / 1024);
    for (j = 0; j < 10; j++) {
        t1 = mysecond();
        for (i = 0; i < N; i++) {
            // Write data to array memory.
            mem[i] = 9.9;
        }
t2 = mysecond();

        // Skip the first iteration for warmup.
        if (j != 0) {
            w_cost += t2 - t1;
        }
    }

    // The MBps is 1000 * 1000 bytes per second.
    printf("Write: cost %lf seconds, bandwidth %lf MBps\n",
            w_cost, 9.0 * N * sizeof(double) * 1.0E-06 / w_cost);

    printf("Test reading %ld MB data for 10 times...\n", N * sizeof(double) / 1024 / 1024);
    for (j = 0; j < 10; j++) {
        t1 = mysecond();
        for (i = 0; i < N; i++) {
            // Read data from array memory to register.
            tmp = mem[i];
        }
        t2 = mysecond();

        // Skip the first iteration for warmup.
        if (j != 0) {
            r_cost += t2 - t1;
        }
    }

    printf("Read:  cost %lf seconds, bandwidth %lf MBps\n",
            r_cost, 9.0 * N * sizeof(double) * 1.0E-06 / r_cost);

    return 0;
}

需要注意的是,这里的设计基于简单的冯洛伊曼计算机架构,使用指令对数据进行搬运。而现代处理器及整个计算机架构已经变得十分复杂,可以预见该测试程序在不同的计算机上的测试表现将会有较大不确定性。请您小心使用。

扩展参考:

stream 官网:http://www.cs.virginia.edu/stream/ref.html

stream 作者对 stream 的解读:https://stackoverflow.com/questions/56086993/what-does-stream-memory-bandwidth-benchmark-really-measure

2019年11月25日

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页