Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 4插槽NUMA系统上的矩阵乘法效率低下_Multithreading_Openmp_Matrix Multiplication_Numa_Tbb - Fatal编程技术网

Multithreading 4插槽NUMA系统上的矩阵乘法效率低下

Multithreading 4插槽NUMA系统上的矩阵乘法效率低下,multithreading,openmp,matrix-multiplication,numa,tbb,Multithreading,Openmp,Matrix Multiplication,Numa,Tbb,我正在开发密集矩阵乘法代码()来学习并行编程。我使用OpenMP进行线程处理。我的系统有四个插座,每个插座带有Xeon E5-1620处理器。每个处理器有10个内核/20个超线程。因此,总共是40个内核/80个超线程。当我在一个线程上运行代码时,我得到了大约70%的峰值失败率(19.2 GFLOPS中的13次)。然而,当我使用40个线程运行我的代码时,我只得到大约30%的峰值失败率(682.56 GFLOPS中的185次)。在一个只有一个插槽和四个内核的独立系统(Sandy Bridge)上,我

我正在开发密集矩阵乘法代码()来学习并行编程。我使用OpenMP进行线程处理。我的系统有四个插座,每个插座带有Xeon E5-1620处理器。每个处理器有10个内核/20个超线程。因此,总共是40个内核/80个超线程。当我在一个线程上运行代码时,我得到了大约70%的峰值失败率(19.2 GFLOPS中的13次)。然而,当我使用40个线程运行我的代码时,我只得到大约30%的峰值失败率(682.56 GFLOPS中的185次)。在一个只有一个插槽和四个内核的独立系统(Sandy Bridge)上,我用四个线程获得了大约65%的效率

我将线程绑定到每个物理核心。我曾尝试禁用此功能,并使用导出OMP_PROC_BIND=true或导出GOMP_CPU_AFFINITY=“0 4 8 12 16 20 24 28 32 36 1 5 9 13 21 25 29 33 37 2 6 10 14 18 22 26 30 34 38 3 7 11 19 23 31 39”,但这些都没有区别。我仍然可以获得大约30%的效率(尽管在其他糟糕的绑定设置下效率会更差)

我还能做些什么来提高我的效率呢?我知道使用了a,所以内存页由第一个接触它们的线程分配。当我写出矩阵积时,也许我应该为每个套接字单独输出,然后在最后合并每个套接字的结果

我正在使用GCC4.8.0和Linux 64位内核2.6.32

编辑:我对矩阵大小=2048x2048使用以下绑定

export GOMP_CPU_AFFINITY="0 4 8 12 16 20 24 28 32 36 1 5 9 13 17 21 25 29 33 37 2 6 10 14 18 22 26 30 34 38 3 7 11 15 19 23 27 31 35 39"
这应该有线程0-9->node 0、10-19 node 1、20-29 node 2、30-39 node 3

通过这种绑定,我得到:

 nthread    efficiency    node
 1          77%           0
 2          76%           0
 4          74%           0
 6          62%           0
 8          64%           0
10          52%           0
14          50%           0+1
16          30%           0+1

有理由怀疑,效率的下降也是因为过多的跨套接字通信。但是设置线程关联性不足以避免这些通信,它应该在算法级别上解决,例如,以最小化跨numa节点交互的方式划分工作。最好的方法是以并行方式实现,例如,不是通过行或列,而是通过二维分幅来并行

例如,您可以使用::
parallel\u For
blocked\u range2d
来更有效地使用缓存


并行度越高,效率越低,这也表明没有足够的工作来证明同步开销的合理性。

您是否有“算法级”的来源或示例。我应该如何更改算法以更好地为NUMA工作?在没有足够的工作,那么我应该看到一些改善矩阵大小。默认情况下,我测试2048x2048矩阵,但我可以尝试更大的矩阵。对于具有40个线程的8192x8192矩阵,效率约为40%(有时高达44%)。我已经在使用2D平铺。没有它们,我不可能获得70%的效率(一个线程)。请记住,在非NUMA system.BTW上使用四个线程可以获得65%。GOMP_CPU_AFFINITY=“0 4 8 12 16 20 24 28 32 36 1 5 9 13 17 21 25 29 33 37 2 6 10 14 22 26 30 34 38 3 7 11 19 23 31 35 39”是一种尽量减少跨numa节点交互的尝试。Linux拓扑分散了CPU,因此线程0 4 8 12 16 20 24 28 32 36对应于同一个节点。@Zboson,您的65%用于4个线程,而不是40。。差别很大。您可以通过运行4个线程(每个套接字一个)来检查NUMA是否影响您以及如何影响您。除了nthread之外,还可以查看它如何映射到NUMA节点,例如nthreads\u node1、nthreads_node2@Anton,使用我选择的绑定,t应该是线程0-9->节点0,10-19节点1,20-29节点2,30-39节点3@Anton事实上它不是那么稳定,效率是60,16个线程一段时间,然后有时下降到30%。n=2048似乎太小了。了解效率如何依赖于节点间的分布也很有用。e、 你的“16”很可能是10:node1+6:node2,那么8:node1+8:node2是什么呢?或者4:node1+4:node2+4:node3+4:node4您可能还需要提高基准测试的稳定性-预热线程以排除测量中的初始化,并可能运行更多的乘法迭代(但缓存局部性可以帮助重复运行,根据您的需要可能是误报)好的,让我做一些测试。如果我使用ICC和KMP_AFFINITY而不是GCC,这会容易得多。我可以写我自己的版本。也许我应该这么做。顺便说一句,谢谢你帮我。