performance - 并行地,在OpenMP并行代码中,运行memset有什么好处?

  显示原文与译文双语对照的内容
0 0

我的内存块可能非常大( 大于L2缓存),有时我都必须将它们设置为零。 memset中好的串行代码,但并行代码呢? 实际上已经有人体验从并发线程如果调用memset加快进度对于大数组? 甚至使用简单的openmp并行for循环?

时间:原作者:5个回答

0 0

人民HPC通常说一个线程通常不够饱和单个内存链接,相同通常对于网络链路也很真实。 Here 是一个快速但不启用OpenMP memsetter我写给你,填充用零2 GiB两倍的内存。 这里是结果使用GCC 4 .7不同的体系结构上使用不同的线程数( max值从多个运行报告) :

gcc 4 .7,代码编译的 -O3 -mtune=native -fopenmp:

Quad socket Intel Xeon X7350 pre Nehalem四核CPU使用单独的存储器控制器和Front Side Bus

单一插槽

threads   1st touch      rewrite
1         1452.223 MB/s  3279.745 MB/s
2         1541.130 MB/s  3227.216 MB/s
3         1502.889 MB/s  3215.992 MB/s
4         1468.931 MB/s  3201.481 MB/s

( 第1 更改速度慢如team正在从头开始创建线程和操作系统是映射物理页面到虚拟地址空间保留的 malloc(3))

一个线程已经饱和该色的内存带宽单个CPU < > nb链接。 ( nB = 北Bridge )

1 线程每个插槽

threads   1st touch      rewrite
1         1455.603 MB/s  3273.959 MB/s
2         2824.883 MB/s  5346.416 MB/s
3         3979.515 MB/s  5301.140 MB/s
4         4128.784 MB/s  5296.082 MB/s

两个线程所必需的完整内存带宽饱和NB < >内存链接。

Octo socket Intel Xeon X7550 8 方式NUMA为octo核心CPU的系统( HT禁用)

单一插槽

threads   1st touch      rewrite
1         1469.897 MB/s  3435.087 MB/s
2         2801.953 MB/s  6527.076 MB/s
3         3805.691 MB/s  9297.412 MB/s
4         4647.067 MB/s  10816.266 MB/s
5         5159.968 MB/s  11220.991 MB/s
6         5330.690 MB/s  11227.760 MB/s

至少5 线程所必要的饱和的带宽单个QPI链接。

1 线程每个插槽

threads   1st touch      rewrite
1         1460.012 MB/s  3436.950 MB/s
2         2928.678 MB/s  6866.857 MB/s
3         4408.359 MB/s  10301.129 MB/s
4         5859.548 MB/s  13712.755 MB/s
5         7276.209 MB/s  16940.793 MB/s
6         8760.900 MB/s  20252.937 MB/s

带宽比例几乎是呈线性的线程数。 基于单一插槽观察有人说那至少40线程分布为5 线程数下有必要为了饱和所有8 QPI链接。

basic上存在问题NUMA系统是第一个触摸内存策略上分配的内存NUMA节点执行的线程在哪里第一次触摸相应的虚拟地址。 线程钉住( 绑定到特定CPU核心),必须在这些系统上为线程迁移会导致远程访问,这也很慢 支持pinnig可用于大多数OpenMP运行库的但仍然不存在可移植的方式来指定它( 它可能会进来OpenMP 3 。2 ) 。 GCC, libgomp具有 GOMP_CPU_AFFINITY环境变量,intel有 KMP_AFFINITY环境变量等。

EDIT : 出于完整性的考虑,他的成果就上运行代码并显示1 GiB数组与 Macbook Air Intel Core i5 2557M ( 双核Sandy Bridge与HT CPU和QPI ) 。 编译器GCC 4 .2 .1 ( Apple LLVM build )

threads   1st touch      rewrite
1         2257.699 MB/s  7659.678 MB/s
2         3282.500 MB/s  8157.528 MB/s
3         4109.371 MB/s  8157.335 MB/s
4         4591.780 MB/s  8141.439 MB/s

为什么这具有速度高,即使是单线程? 一个小小探索, gdb表明, memset(buf, 0, len)获取转换的OS X 编译器 bzero(buf, len)并且有一条SSE4 .2启用矢量化版本的名称后 bzero$VARIANT$sse42提供的是 libc.dylib并在运行时使用。 它将使用 MOVDQA指令为零16字节内存一次。 所以即使使用一个线程的内存带宽几乎是饱和了。 单线程AVX启用版本使用 VMOVDQA马上就能零32字节大概饱和QPI链接。

关键讯息的是有时vectorisation和多进程不正交方面一直加速到操作。

原作者:
0 0

好吧,总有L3缓存。。。

但是,很可能这只获得主内存带宽已经不可能为改进,添加更多的并行。

原作者:
...