STREAM内存带宽测试工具介绍及其内部实现
lmbench中有stream,https://github.com/keith-packard/lmbench3
但是版本有点旧。
我们用的是版本更新一点的V5.10 2013/01/17 , 代码地址:
GitHub - jeffhammond/STREAM: STREAM benchmark
传送门:
intel平台可以使用官方的内存测试工具
Intel® Memory Latency Checker v3.9a
一、编译命令
gcc -O3 -fopenmp -DSTREAM_ARRAY_SIZE=2000000 stream.c -o stream.2M
gcc -O3 -fopenmp -DSTREAM_ARRAY_SIZE=20000000 stream.c -o stream.20M#risc-v platform
gcc -O3 -fopenmp -DSTREAM_ARRAY_SIZE=80000000 stream.c -o stream.80M -mexplicit-relocs
1. –fopenmp
适应多处理器环境。开启后,程序默认线程为CPU线程数,也可以运行时也可以动态指定运行的进程数,12为自定义的要使用的处理器数。
export OMP_NUM_THREADS=12
2. -DSTREAM_ARRAY_SIZE
计算方法参考stream.c中的说明,举例:u540的 L2缓存 2MB,其值为
double类型占8 Byte,每个ARRAY的大小是 STREAM_ARRAY_SIZE * 8Byte。
每个ARRAY的大小要超过4倍的缓存大小,即:
STREAM_ARRAY_SIZE * 8B > 4 * 2MB
可得STREAM_ARRAY_SIZE最小需要为1M,在这里作者并不区分1M是10的6次方,还是2的20次方,因为4倍大小已经远远大于缓存,能够保证访存到达内存而不是访问到缓存。这个值是最小值,可以适当大于此值,增大array size会增加测试时间,也会保证测试过程至少经历20个clock ticks。
下面是代码中关于STREAM_ARRAY_SIZE的说明:
* 1) STREAM requires different amounts of memory to run on different
* systems, depending on both the system cache size(s) and the
* granularity of the system timer.
* You should adjust the value of 'STREAM_ARRAY_SIZE' (below)
* to meet *both* of the following criteria:
* (a) Each array must be at least 4 times the size of the
* available cache memory. I don't worry about the difference
* between 10^6 and 2^20, so in practice the minimum array size
* is about 3.8 times the cache size.
* Example 1: One Xeon E3 with 8 MB L3 cache
* STREAM_ARRAY_SIZE should be >= 4 million, giving
* an array size of 30.5 MB and a total memory requirement
* of 91.5 MB.
* Example 2: Two Xeon E5's with 20 MB L3 cache each (using OpenMP)
* STREAM_ARRAY_SIZE should be >= 20 million, giving
* an array size of 153 MB and a total memory requirement
* of 458 MB.
* (b) The size should be large enough so that the 'timing calibration'
* output by the program is at least 20 clock-ticks.
* Example: most versions of Windows have a 10 millisecond timer
* granularity. 20 "ticks" at 10 ms/tic is 200 milliseconds.
* If the chip is capable of 10 GB/s, it moves 2 GB in 200 msec.
* This means the each array must be at least 1 GB, or 128M elements.
3. –DNTIMES
NTIMES是执行次数,默认值是10,所有测试,结束后从结果中取最优,第一轮测试的结果不参与最终统计。
4. -mexplicit-relocs
当STREAM_ARRAY_SIZE太大时,gcc编译会出错,需要使用此选项更改代码链接时的分布。
参见:
RISC-V Options (Using the GNU Compiler Collection (GCC))
如果是x64平台,当STREAM_ARRAY_SIZE比较大时,(大于100MB可能)编译会出错,需要给gcc添加 选项 -mcmodel=large
参考: x86 Options (Using the GNU Compiler Collection (GCC))
二、在u540上的测试结果
在u540上的测试结果如下表所示,可以看到当STREAM_ARRAY_SIZE非常小的时候,测试1和测试2得到的内存带宽结果会比较大,是因为用到了缓存。当STREAM_ARRAY_SIZE大于2M时,最终测得的结果稳定在1300MBps左右。
表4.1 u540上STREAM测试结果
测试序号 |
STREAM_ARRAY_SIZE (MB) |
内存带宽测试结果(MBps) |
备注 |
1 |
20K |
4034.6 |
用到cache |
2 |
100K |
2307.7 |
用到cache |
3 |
2M |
1272.8 |
以下结果比较接近 |
4 |
20M |
1314.1 |
|
5 |
80M |
1258.8 |
|
6 |
130M |
1295.7 |
三、一个测试结果输出
root@freedom-u540:~/work/STREAM-master# ./stream.20M
-------------------------------------------------------------
STREAM version $Revision: 5.10 $
-------------------------------------------------------------
This system uses 8 bytes per array element.
-------------------------------------------------------------
Array size = 20000000 (elements), Offset = 0 (elements)
Memory per array = 152.6 MiB (= 0.1 GiB).
Total memory required = 457.8 MiB (= 0.4 GiB).
Each kernel will be executed 10 times.The *best* time for each kernel (excluding the first iteration)will be used to compute the reported bandwidth.
-------------------------------------------------------------
Number of Threads requested = 4
Number of Threads counted = 4
-------------------------------------------------------------
Your clock granularity/precision appears to be 1 microseconds.
Each test below will take on the order of 170454 microseconds.(= 170454 clock ticks)
Increase the size of the arrays if this shows that
you are not getting at least 20 clock ticks per test.
-------------------------------------------------------------
WARNING -- The above is only a rough guideline.
For best results, please be sure you know the
precision of your system timer.
-------------------------------------------------------------
Function Best Rate MB/s Avg time Min time Max time
Copy: 1455.5 0.222349 0.219856 0.229256
Scale: 1205.2 0.266443 0.265518 0.267343
Add: 1309.9 0.368384 0.366434 0.371048
Triad: 1314.1 0.367992 0.365281 0.371307
四、STREAM内部实现
- 避免Cache影响
当CPU要读取一个数据时,首先从Cache缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。
STREAM通过设置STREAM_ARRAY_SIZE,定义远大于缓存容量的内存数组变量,按顺序从内存中进行读取或写入,由于数据量远大于缓存容量,可以避免缓存对测试结果的影响。
- 四种操作
STREAM对内存进行Copy、Scale、Add、Triad四种操作。
Copy操作最为简单,它先访问一个内存单元读出其中的值,再将值写入到另一个内存单元。Scale操作先从内存单元读出其中的值,作一个乘法运算,再将结果写入到另一个内存单元。Add操作先从内存单元读出两个值,做加法运算, 再将结果写入到另一个内存单元。Triad的中文含义是将三个组合起来,在本测试中表示的意思是将Copy、Scale、Add三种操作组合起来进行测试。具体操作方式是:先从内存数组中读两个值a、b,对其进行乘加混合运算(a+因子* b),将运算结果写入到另一个内存单元。
假定每次操作的内存读写字节数:
测试结果一般的规律是Add > Triad > Copy > Scale。一次Add操作需要访问三次内存(两个读操作,一个写操作),Triad操作也需要三次访问内存, Copy和Scale操作只需要两次访问内存。单位操作内,访问内存次数越多,带宽越大。另一方面,单位操作内,浮点计算次数越多,操作完成时间越长,导致整个操作循环完成的时间越长,带宽越低。Add操作简单且访存次数多,故而带宽最大,Scale操作复杂且访存次数少,故而带宽最小。
- 具体代码
定义三个大数组a、b和c,数组大小为STREAM_ARRAY_SIZE+OFFSET,OFFSET一般为0,STREAM_ARRAY_SIZE通过编译器指定。
#ifndef STREAM_TYPE
#define STREAM_TYPE double
#endif
static STREAM_TYPE a[STREAM_ARRAY_SIZE+OFFSET],
b[STREAM_ARRAY_SIZE+OFFSET],
c[STREAM_ARRAY_SIZE+OFFSET];
测试主体流程:在一个大循环中运行NTIMES次测试,每次测试分别运行Copy、Scale、Add、Triad四种测试,每种测试结束后会记录所用的时间,用于后期计算内存带宽。
calar = 3.0;
for (k=0; k<NTIMES; k++)
{
#pragma omp parallel for
for (j=0; j<STREAM_ARRAY_SIZE; j++)
c[j] = a[j];
#pragma omp parallel for
for (j=0; j<STREAM_ARRAY_SIZE; j++)
b[j] = scalar*c[j];
#pragma omp parallel for
for (j=0; j<STREAM_ARRAY_SIZE; j++)
c[j] = a[j]+b[j];
#pragma omp parallel for
for (j=0; j<STREAM_ARRAY_SIZE; j++)
a[j] = b[j]+scalar*c[j];
}
- 内存带宽的计算
内存带宽计算公式:
内存带宽=搬运的内存大小/耗时
STREAM在计算时跳过第1次的结果,避免系统冷启动时的误差。
bytes数组中的初始值是Copy、Scale、Add、Triad等操作完成一次的总字节数
static double bytes[4] = {
2 * sizeof(STREAM_TYPE) * STREAM_ARRAY_SIZE,
2 * sizeof(STREAM_TYPE) * STREAM_ARRAY_SIZE,
3 * sizeof(STREAM_TYPE) * STREAM_ARRAY_SIZE,
3 * sizeof(STREAM_TYPE) * STREAM_ARRAY_SIZE
};
for (k=1; k<NTIMES; k++) /* note -- skip first iteration */
{
for (j=0; j<4; j++)
{
avgtime[j] = avgtime[j] + times[j][k];
mintime[j] = MIN(mintime[j], times[j][k]);
maxtime[j] = MAX(maxtime[j], times[j][k]);
}
}
printf("Function Best Rate MB/s Avg time Min time Max time\n");
for (j=0; j<4; j++) {
avgtime[j] = avgtime[j]/(double)(NTIMES-1);
printf("%s%12.1f %11.6f %11.6f %11.6f\n", label[j],
1.0E-06 * bytes[j]/mintime[j],
avgtime[j],
mintime[j],
maxtime[j]);
}
参考:
John McCalpin's blog » STREAM benchmark
Stream Benchmark - OpenBenchmarking.org
latency and bandwidth micro benchmarks
STREAM内存带宽测试工具介绍及其内部实现相关推荐
- bandwidth 0.32k 发布,内存带宽测试工具
bandwidth 0.32k 修复了一些小的 AVX 问题. Bandwidth 是一个内存带宽测试的基准工具,但它也可以测量网络带宽.它可以测量每个内存系统的最大内存带宽,包括主内存,L1和L2缓 ...
- 【开发工具】【stream】内存带宽测试工具(Stream)的使用
获取更多相关的嵌入式开发工具,可收藏系列博文,持续更新中: [开发工具]嵌入式常用开发工具汇总帖 Stream简介 STREAM是一套综合性能测试程序集,通过fortran和C两种高级且高效的语言编写 ...
- Linux下stream内存带宽测试参数和示例详解附源码(总结)
目录 一.简介 二.使用简介 2.1 测试内容简介 2.2 编译参数简介 2.3 具体参数示例 三.源码下载及使用 四.其他相关知识链接 FIO测试硬盘性能参数和实例总结 一.简介 本文通过实例详细讲 ...
- stream.c 内存带宽测试
内存带宽测试工具:stream 介绍 Stream测试是内存测试中业界公认的内存带宽性能测试基准工具,作为衡量服务器内存性能指标的通用工具. 2. 原理 申请了三个巨大的双精度浮点数组a[N], b[ ...
- iOS 开发之使用苹果测试工具 TestFlight (进行内部和外部测试)
一.测试工具介绍: 1.TestFlight是苹果公司在iOS8,Xcode6推出来的新工具,用于将App beta版本进行流水化测试.TestFlight整合进了Appstore Connect,你 ...
- 测试大白菜软件,大白菜memtest内存清理测试工具的简介
我们都知道电脑用久了,系统内存会随着程序的运行而增加垃圾文件,从而影响到电脑性能,虽然很多朋友想着要清理电脑的系统内存,但又苦于不知从何下手,今天就给大家介绍下使用u深度memtest内存清理工具来进 ...
- 4测试命令_局域网带宽测试工具-iPerf3
工具名称:iPerf3 官网: https://iperf.fr/ 简介:用于TCP,UDP和SCTP的终极速度测试工具: 功能:跨平台(Windows,Linux,Android,MacOS X,F ...
- 默蓝网络通信TCP/HTTP测试工具介绍
默蓝网络通信TCP/HTTP测试工具介绍 默蓝网络通信TCP/HTTP测试工具为广大技术开发人员提供的通信测试工具,其具备如下功能: 1.支持TCP/IP协议的网络通信,TCP服务端和客户端,可单条发 ...
- Fortify SCA 源代码安全测试工具-----介绍
Fortify SCA 源代码安全测试工具-----介绍 关于fortify成立于2003年的Fortify Software是全球领先的软件安全产品解决方案供应商. ...
- Android内存压力测试工具(memtester移植)
该文章转载于: android用memtester内存压力测试_W歹匕示申W的博客-CSDN博客 Android内存压力测试工具(memtester移植)_甜牛奶蛋糕的博客-CSDN博客_androi ...
最新文章
- 众测 Nebula Graph | 捉虫计划已开启,这项有礼
- ECCV 2018 | 腾讯AI Lab提出视频再定位任务,准确定位相关视频内容
- 差距50倍!为什么Web API第一次执行这么慢?
- 开关灯(信息学奥赛一本通-T1109)
- html连接数据库id号自动生成器,SQL Server数据库sql语句生成器(SqlDataToScript)的使用(sql server自增列(id)插入固定值)...
- idea swing 插件_【分享】我的idea配置
- TensorFlow 实战(五)—— 图像预处理
- MaxDOS V7 PXE网刻教程
- css3实现缺角四边形_CSS3实现缺角矩形,折角矩形以及缺角边框
- boost创建线程池_linux下boost的一个扩展线程池-threadpool-的学习
- linux awk比较大小,linux基础只是之awk命令使用,统计最大长度
- 什么是HSS?HSS有什么主要功能?HSS与HLR的区别是什么
- Win10,详细永久关闭更新方法(附图文)
- ROS2机器人笔记20-11-29
- cos相似度算法 余弦距离计算
- java将数组加上千分号_[宜配屋]听图阁
- Oracle的sqlplus使用,sqlplus命令的使用-Oracle
- JEECG 3.7.1版本发布,企业级JAVA快速开发平台
- 阿里云企业邮箱的stmp服务器地址
- C# 代码规范和质量检查工具 StyleCop.Analyzers
热门文章
- 大数运算:Barrett And Montgomery
- python用input输入整数列表_Python用input输入列表的方法
- 三原色是红黄蓝对吗_为什么三原色是红黄蓝而?
- 适合WhatsApp网页版的4个最好的免费WhatsApp 群发工具
- QUIC特性之连接迁移和队头阻塞消除
- DNA 5. 基因组变异文件VCF格式详解
- 鼠标右键没有新建选项怎么办
- 【机器学习】几种常见的有监督学习算法
- YOLO: 3 步实时目标检测安装运行教程 [你看那条狗,好像一条狗!]
- Failed to read artifact descriptor for com.google.errorprone:javac:jar:9+181-r4173-1