英文原版 https://www.cs.virginia.edu/stream/ref.html

FAQ中有关于STREAM_ARRAY_SIZE NTIME OFFSET STREAM_TYPE的设置说明

在stream.c的源码中也有。

最近由于工作需要,接触到Stream benchmark。Stream benchmark是一个测试内存带宽的基准测试程序。官方提供C和fortran两个版本,鉴于如今C语言使用的广泛形,本文仅从C语言版本的测试进行分析。关于Stream benchmark 的相关文档请查看https://www.cs.virginia.edu/stream/
1. 下载。要运行Stream benchmark, 首先需要下载。下载基准测试程序请移步https://www.cs.virginia.edu/stream/FTP/Code/。如果是使用C,你只需要下载一个文件stream.c。

2. 编译。如果是C程序源码,你可以使用gcc或g++进行编译。编译使用

                                         
gcc -O stream.c -o stream_exe
   
你也可以加入openmp编译选项进行多核访存带宽的测试,加入openmp选项的编译使用
                               
gcc -O -fopenmp stream.c -o stream_omp_exe
   
本程序有三个重要参数需要设置,他们是STREAM_ARRAY_SIZE,NTIMES以及OFFSET。关于这三个参数的含义和设置规则我将在下文详细介绍。设置这三个参数的方法有两种,一是直接在源文件中修改,二是在编译选项中加入编译规则,即使用-D
选项定义。如要定义STREAM_ARRAY_SIZE为100M,NTIMES为12以及OFFSET为2,则使用以下编译方法
    gcc -O
-fopenmp -DSTREAM_ARRAY_SIZE=100000000 -DNTIME=12 -DOFFSET=1022
stream.c -o stream_omp_exe
   
如果设置的STREAM_ARRAY_SIZE太大(大于2G),你可以增加编译选项-mcmodel=medium,如果继续增大这个size,可以进一步使用-mcmodel=large。除此之外,你还可以定义STREAM_TYPE,默认是double,基本不许要修改。

3.
运行及结果分析。直接使用./stream_omp_exe即可运行,如果多线程并未启动,可在运行前手动设置运行的进程数,如export
OMP_NUM_THREADS=20。以下是某Power机器上的运行结果
                        
-------------------------------------------------------------
                        
STREAM version $Revision: 5.10 $
                        
-------------------------------------------------------------
                        
This system uses 8 bytes per array element.
                        
-------------------------------------------------------------
                        
Array size = 100000000 (elements), Offset = 0 (elements)
                        
Memory per array = 762.9 MiB (= 0.7 GiB).
                        
Total memory required = 2288.8 MiB (= 2.2 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 = 20
                        
Number of Threads counted = 20
                        
-------------------------------------------------------------
                        
Your clock granularity/precision appears to be 1
microseconds.
                        
Each test below will take on the order of 13857 microseconds.
                        
   (= 13857 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:         
134965.4    
0.012672    
0.011855    
0.013730
                        
Scale:        
132362.0    
0.013659    
0.012088    
0.017100
                        
Add:          
141218.4    
0.018251    
0.016995    
0.019597
                        
Triad:        
136666.8    
0.018566    
0.017561    
0.019594
                        
-------------------------------------------------------------
                        
Solution Validates: avg error less than 1.000000e-13 on all three
arrays
                        
-------------------------------------------------------------
上述结果已经很清晰显示各种信息了,在这里不赘述。下面着重讲一下4个操作Copy,Scale,Add和Triad。
Copy为最简单的操作,即从一个内存单元中读取一个数,并复制到另一个内存单元,有2次访存操作。
Scale是乘法操作,从一个内存单元中读取一个数,与常数scale相乘,得到的结果写入另一个内存单元,有2次访存。
Add是加法操作,从两个内存单元中分别读取两个数,将其进行加法操作,得到的结果写入另一个内存单元中,有2次读和1次写共3次访存。

Triad是前面三种的结合,先从内存中读取一个数,与scale相乘得到一个乘积,然后从另一个内存单元中读取一个数与之前的乘积相加,得到的结果再写入内存。所以,有2次读和1次写共3次访存操作。

从上述的结果我们可以看出,测试的内存带宽Add>Triad>Copy>Scale。这是因为访存次数越多,内隐藏的访存延迟越大,得到的带宽越大。同理,运算的操作越复杂,操作时间就越长,程序运行时间就越长,得到的访存带宽就相应减少。这就是为什么3次访存的操作得到的带宽比2次访存操作得到的要大,而相同访存次数的操作,加法要比乘法得到的结果要好。

4. 参数含义及设置规则。
   
1)STREAM_ARRAY_SIZE。这个是测试数据集的大小,该大小应该遵循以下两条规则。
       
A. 数据集大小应不小于L3 cache大小的4倍。举例来说某10核Power机器中L3 cache为8MB/core,共80MB
L3
cache,因此数据集的大小至少为80MB*4=320MB。由于数据集中每个元素大小为64bits,即8B。故,数据集大小应设置为不小与320MB/8B=40M
(40million或40000000)。
       
B. 数据集大小应能确保程序输出时间大于20个时钟周期。该时钟周期可在程序输出信息中看到,如“Your clock
granularity/precision appears to be 1 microseconds.“
表示时钟周期为1微秒,20个时钟周期为20微秒。如果你的测试机器有200GB/s的带宽,那你的数据集大小应不小于4MB,即0.5million个元素。

2)
NTIME。该参数为kernel执行的次数,程序将输出除第一次外其他结果中最好的结果,所以NTIME必须要大于1。该值默认为10,通常不许要修改。

3)OFFSET。该值为数组的偏移量,修改此值可改变数组的对齐,从而在一定程度上改变输出的性能结果。一定程度在这指的是也许会改变,也许不会改变。本人在Power上的测试是没有很大的改变。如果需要修改该参数,通常将其设置为靠近2^n的数,例如使用-DOFFSET=1022
(靠近2^10=1024)。
    4)
STREAM_TYPE。我们可以通过修改该参数设置测试集的数据类型,默认是double(8B)。如果将其改为float则数据集大小减少一半。

Stream benchmark已经推出stream2.0版本,相关资料及源码下载请参考https://www.cs.virginia.edu/stream/stream2/。最后感谢John和McCalpin提供这么简单粗暴方便有效的测试方式。

 

stream benchmark 介绍的更多相关文章

  1. STREAM Benchmark

    STREAM Benchmark及其操作性能分析 文/raywill STREAM 是业界广为流行的综合性内存带宽实际性能 测量 工具之一.随着处理器处理核心数量的增多,内存带宽对于提升整个系统性能越 ...

  2. STREAM Benchmark及其操作性能分析

    STREAM 是业界广为流行的综合性内存带宽实际性能 测量 工具之一.随着处理器处理核心数量的增多,内存带宽对于提升整个系统性能越发重要,如果某个系统不能够足够迅速地将内存中的数据传输到处理器当中,若 ...

  3. 2020你还不会Java8新特性?方法引用详解及Stream 流介绍和操作方式详解(三)

    方法引用详解 方法引用: method reference 方法引用实际上是Lambda表达式的一种语法糖 我们可以将方法引用看作是一个「函数指针」,function pointer 方法引用共分为4 ...

  4. 性能工具 stream 最新版本5.10 The STREAM benchmark

    官网下载最新性能工具 stream 最新版本5.10 https://github.com/jeffhammond/STREAM 官网下载最新性能工具 stream 最新版本5.10   http:/ ...

  5. [Java 8 Lambda] java.util.stream 简单介绍

    包结构例如以下所看到的: 这个包的结构非常easy,类型也不多. BaseStream接口 全部Stream接口类型的父接口,它继承自AutoClosable接口,定义了一些全部Stream都具备的行 ...

  6. stream benchmark 交叉编译 on psoc

    之前有研究过这个,居然忘记了,看来确实是老了,没有盘过来. 如何下载,见 linux下载网页上的文件夹以及删除文件(stream) 出现了好几个问题 1. error while loading sh ...

  7. MongoDB 变更流(Change Stream)介绍

    1. 什么是Change Stream Change Stream 是MongoDB用于实现变更追踪的解决方案,类似于关系数据库的触发器,但原理不完全相同: | | Change Stream | 触 ...

  8. Spring Cloud Stream介绍-Spring Cloud学习第八天(非原创)

    文章大纲 一.什么是Spring Cloud Stream二.Spring Cloud Stream使用介绍三.Spring Cloud Stream使用细节四.参考文章 一.什么是Spring Cl ...

  9. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...

随机推荐

  1. Day2 01 引用类型和值类型

    值类型:值类型变量,存储的是对象的值.给其赋值,会创建值的副本,修改任何一个副本,不会影响其他副本. int x = 5; int y = x;  //创建一个x的副本y  x把其自身的值传送给了y ...

  2. 自定义控件 - 字母索引 : LetterIndexView

    实现字母列表,滑动列表显示当前选中字母,回调接口. 1.实现字母列表.初始化相关属性.计算每个字母所占宽高.绘制字母A-Z,#. private int itemWidth;//每个字母所占宽度 pr ...

  3. 二十九、pycharm中报错“too many blank lines (3) ”等类似错误

    报错如下图: 解决方法一: 鼠标移至报错处,按住Alt+enter键,选择ignore errors like this 方法二:找到设置File - Settings…… - Editor - In ...

  4. 二十五、python中pickle序列学习(仅python语言中有)

    1.pickle序列介绍:提供4个关键字:dumps,dump,loads,load 语法:f.write(pickle.dumps(dict))=pickle.dump(dict,f) " ...

  5. 【C++】fill函数,fill与memset函数的区别

    转载自:https://blog.csdn.net/liuchuo/article/details/52296646 memset函数 按照字节填充某字符在头文件<cstring>里面fi ...

  6. jmeter之三种参数化

    前言:总结并记录几种jmeter比较有用的元件 1.接口文档 2.参数化 3.断言 1.接口文档 a.拿到接口文档 接口地址:http://localhost:8080/jpress/admin/lo ...

  7. Linux 服务器安全优化

    最小的权限+最少的服务=最大的安全 所以,无论是配置任何服务器,我们都必须把不用的服务关闭.把系统权限设置到最小,这样才能保证服务器最大的安全.下面是CentOS服务器安全设置,供大家参考. 一.注释 ...

  8. Redux 中间件与函数式编程

    为什么需要中间件 接触过 Express 的同学对"中间件"这个名词应该并不陌生.在 Express 中,中间件就是一些用于定制对特定请求的处理过程的函数.作为中间件的函数是相互独 ...

  9. Spring Boot系列(四) Spring Boot 之验证

    这节没有高深的东西, 但有一些学习思路值得借鉴. JSR 303 (Bean Validation) Maven依赖 <dependency> <groupId>org.spr ...

  10. 20190903 On Java8 第十七章 文件

    第十七章 文件 在Java7中对 文件的操作 引入了巨大的改进.这些新元素被放在 java.nio.file 包下面,过去人们通常把nio中的n理解为new即新的io,现在更应该当成是non-bloc ...