服务器内存带宽测试方法【stream】
一 概述
内存带宽为处理器可以从内存读取数据或将数据存储到内存的速率
具体计算方式可以举例说明如下:
节点单节点理论内存带宽=3200MHz*64bit*8通道*2颗CPU/8bit/1024=400GB/s
二 编译
内存带宽一般采用stream.c程序进行编译,根据笔者的经验,Intel编译器编译得到的程序性能较优,基本上测试出来的内存带宽都在理论值的70%以上,Intel编译器安装方法可以参考https://docs.aheadai.cn/155.html
Stream的官方下载地址:http://www.cs.virginia.edu/stream/FTP/Code/stream.c
如果官方地址失效,可以使用以下地址:
wget https://mirrors.aheadai.cn/pkgs/stream.c
则编译命令为:
icc -o stream stream.c -DSTATIC -DNTIMES=10 -DSTREAM_ARRAY_SIZE=2500000000 -mcmodel=large -shared-intel -Ofast -qopenmp -ffreestanding -qopt-streaming-stores always
三 测试
测试命令为:
export OMP_PROC_BIND=true
export OMP_NUM_THREADS=64 # 这里的64是所测试节点的CPU总核心数量(建议设置为超线程之前的核心数,即物理核心数)
./stream
测试结果示例为:
-------------------------------------------------------------
STREAM version : 5.10 $
-------------------------------------------------------------
This system uses 8 bytes per array element.
-------------------------------------------------------------
Array size = 2500000000 (elements), Offset = 0 (elements)
Memory per array = 19073.5 MiB (= 18.6 GiB).
Total memory required = 57220.5 MiB (= 55.9 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 = 64
Number of Threads counted = 64
-------------------------------------------------------------
Your clock granularity/precision appears to be 1 microseconds.
Each test below will take on the order of 124275 microseconds.
(= 124275 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: 318423.3 0.125908 0.125619 0.126373
Scale: 319208.5 0.126040 0.125310 0.128203
Add: 320254.5 0.187974 0.187351 0.189735
Triad: 322014.6 0.186867 0.186327 0.189051
-------------------------------------------------------------
Solution Validates: avg error less than 1.000000e-13 on all three arrays
-------------------------------------------------------------
四 结果分析
Stream测试包含Copy、Scale、Add、Triad四种操作:
测试项 | 实际操作 | 访存次数/每循环 | 浮点计算次数/每循环 |
---|---|---|---|
Copy | a(i) = b(i) | 2 | 0 |
Scale | a(i) = q * b(i) | 2 | 1 |
Add | a(i) = b(i) + c(i) | 3 | 1 |
Triad | a(i) = b(i) + q * c(i) | 3 | 2 |
测试结果一般的规律是Add > Triad > Copy > Scale。一次Add操作需要访问三次内存(两个读操作,一个写操作),Triad操作也需要三次访问内存,Copy和Scale操作需要两次访问内存。单位操作内,访问内存次数越多,越能够掩盖访存延迟,带宽越大。另一方面,单位操作内,浮点计算次数越多,操作完成时间越长,导致整个操作循环完成的时间越长,带宽越低。Add操作简单且访存次数多,故而带宽最大,Scale操作复杂且访存次数少,故而带宽最小。
Stream主要的调节参数如下:
- STREAM_ARRAY_SIZE
调节测试数组的大小,可以在编译参数中通过“-DSTREAM_ARRAY_SIZE=”指定,默认为10,000,000。Stream的测试数组类型为双精度浮点,单个数组的占用内存为STREAM_ARRAY_SIZE*8字节(OFFSET为0时)。
如果数组太小,CPU Cache会干扰测试结果,不能测试出真实的内存带宽,如果数组太大,测试时间过长。Stream官方建议数组占用内存达到CPU最后一级Cache的4倍。
另外,如果STREAM_ARRAY_SIZE指定过大,单个数组超过2GB,需要在编译选项中添加“-mcmodel=medium”。
- NTIMES
每次测试运行NTIMES,选取最好的一次输出。可以在编译参数中通过“-DNTIMES=”指定,默认为10。为增加测试结果的稳定性,可以适当增大,但测试时间也会变长。
- OFFSET
调节数组的内存对齐。可以在编译参数中通过“-DOFFSET=”指定,默认为0,一般不用修改。
- STREAM_TYPE
指定测试数组的数据类型,默认为double双精度浮点。可以在编译参数中通过“-DSTREAM_TYPE=float”修改为单精度。一般公认的测试均使用双精度,一般不用修改。
- OpenMP多线程支持
gcc编译器添加“-fopenmp”选项,icc为“-qopenmp”,pgcc为“-mp”,Open64的opencc为“-openmp”。
评论