#include #include #include "clock.h" #define MINBYTES (1 << 11) // 内存测试区域从 2KB 开始 #define MAXBYTES (1 << 26) // 最大到 64 MB #define MAXSTRIDE 64 // 循环步长从 1 到 64 字节 #define MAXELEMS MAXBYTES/sizeof(double) double data[MAXELEMS]; // 测试用的全局内存数组 void init_data(double *data, int n); void run_width_testing(); double get_seque_access_result(int size, int stride, int type); double get_random_access_result(int size, int type); void seque_access(int elems, int stride); void random_access(int* random_index_arr, int count); void create_rand_array(int max, int count, int* pArr); int main() { init_data(data, MAXELEMS); printf("Band Width (MB/sec)\n"); run_width_testing(); printf("\n\n"); exit(0); } // init_data 初始化要访问的内存数据 void init_data(double *data, int n) { int i; for (i = 0; i < n; i++) data[i] = i; } // 运行内存访问带宽测试 void run_width_testing() { int size; // 测试内存区域大小 int stride; // 内存区域访问循环步长 // 打印内存区域大小头信息 printf("\t"); for (size = MAXBYTES; size >= MINBYTES; size >>= 1) { if (size > (1 << 20)){ printf("%dm\t", size / (1 << 20)); }else{ printf("%dk\t", size / 1024); } } printf("\n"); // 多次实验,进行内存顺序访问带宽评估 // 外层循环控制步长依次从 1 到 64,目的是不同的顺序步长的访问效果差异 // 内存循环控制数据大小依次从 2KB 开始到 64MB,目的是要保证数据大小依次超过 L1、L2、L3 for (stride = 1; stride <= MAXSTRIDE; stride=stride+1) { printf("s%d\t", stride); for (size = MAXBYTES; size >= MINBYTES; size >>= 1) { printf("%.1f\t", get_seque_access_result(size, stride, 0)); } printf("\n"); } // 多次实验,进行内存随机访问带宽评估 printf("random\t"); for (size = MAXBYTES; size >= MINBYTES; size >>= 1) { printf("%.1f\t", get_random_access_result(size,0)); } printf("\n"); } // get_seque_access_result 测试存储访问延迟(L1/L2/L3,内存) // 参数说明 // - size: 要测试的数据大小 // - stride: 步长 // - type: 0 获取带宽测试结果 // - 1 获取延时测试结果,单位是 CPU 周期数 double get_seque_access_result(int size, int stride, int type) { int i; long int operations; long int total_accessed_bytes; long int used_microseconds; int samples = 1000; int elems = size / sizeof(double); //循环测试 1000 次,以最大程度减少实验计算结果误差 start_timer(); for(i=0; i