我正在开发大型密集矩阵乘法代码。当我分析代码时,它有时会得到我四核系统峰值失败率的 75% 左右,而其他时候会得到大约 36%。执行代码之间的效率不会改变。它要么从 75% 开始并以该效率继续,要么从 36% 开始并以该效率继续。
我已将问题追溯到超线程以及我将线程数设置为四个而不是默认的八个这一事实。当我在 BIOS 中禁用超线程时,我的效率始终保持在 75% 左右(或者至少我从未看到大幅下降到 36%)。
在我调用任何并行代码之前omp_set_num_threads(4)
。在我运行我的代码之前我也尝试export OMP_NUM_THREADS=4
过,但它似乎是等价的。
我不想在 BIOS 中禁用超线程。我想我需要将四个线程绑定到四个核心。我已经测试了一些不同的情况,GOMP_CPU_AFFINITY
但到目前为止我仍然遇到效率有时为 36% 的问题。 超线程和内核的映射是什么? 例如,线程 0 和线程 1 是否对应同一个核心,线程 2 和线程 3 是否对应另一个核心?
如何在没有线程迁移的情况下将线程绑定到每个内核,这样我就不必在 BIOS 中禁用超线程? 也许我需要考虑使用sched_setaffinity?
我当前系统的一些细节:Linux 内核 3.13,GCC 4.8,Intel Xeon E5-1620(四个物理内核,八个超线程)。
编辑:到目前为止,这似乎运作良好
export GOMP_CPU_AFFINITY="0 1 2 3 4 5 6 7"
或者
export GOMP_CPU_AFFINITY="0-7"
编辑:这似乎也很好用
export OMP_PROC_BIND=true
编辑: 这些选项也很好用(gemm 是我的可执行文件的名称)
numactl -C 0,1,2,3 ./gemm
和
taskset -c 0,1,2,3 ./gemm