【发布时间】:2014-11-18 05:06:19
【问题描述】:
我想为 Xeon Phi(60 核)编写基准测试。在我的程序中,我使用 OpenMP 标准和 Intel 内在函数。我实现了算法的并行版本(5 点模板计算),它比标量算法快 230 倍。我想将 SIMD 添加到并行代码中。我有性能问题。当我调用 _m512_store_pd() 时,计算性能会降低,并且使用 SIMD 的并行版本比没有 SIMD 的版本慢。问题是什么?我应该怎么做才能获得更好的性能?
for(int i=start; i<stop; i+=threadsPerCore)
{
for(int j=8; j<n+8; j+=8)
{
__m512d v_c = _mm512_load_pd(&matrixIn[i * n_real + j]);
__m512d v_g = _mm512_load_pd(&matrixIn[(i - 1) * n_real + j]);
__m512d v_d = _mm512_load_pd(&matrixIn[(i + 1) * n_real + j]);
__m512d v_l = _mm512_loadu_pd(&matrixIn[i * n_real + (j - 1)]);
__m512d v_p = _mm512_loadu_pd(&matrixIn[i * n_real + (j + 1)]);
__m512d v_max = _mm512_max_pd(v_c, v_g);
v_max = _mm512_max_pd(v_max, v_d);
v_max = _mm512_max_pd(v_max, v_l);
v_max = _mm512_max_pd(v_max, v_p);
_mm512_store_pd(&matrixOut[i * n_real + j], v_max);
}
}
我从 8 开始计算,因为我在开头有一个向量,最后一个向量是光环元素。 n_real 是向量的大小 -> n + 16。开始和停止是计算的,因为 60 核的 i 分区矩阵和 opne 部分 (m/60) 由 4 个 HM 线程计算。
【问题讨论】:
-
你不能组织你的数据,以便为结果计算数据吗?我不确定现在情况如何,但使用未对齐的存储来传输数据曾经很糟糕。除此之外,不知道有什么建议。您是否首先查看过编译器生成的代码?当编译器充分了解正在发生的事情以及如何翻译它时,gcc 和 clang 都倾向于生成相当不错的 SIMD 代码——这看起来并不复杂。
-
这是错误的。我不使用“storeu”内在将数据写入内存。矩阵 matrixIn 和 matrixOut 都对齐到 64 字节。当我复制代码时,使用“storeu”它必须是一个错误。对不起。我编译程序: icc -mmic -O3 -openmp
-
好吧,我没有具有正确指令集的机器,也没有 icc(我曾经为 AMD 工作,但仍然不为我自己的机器购买 Intel CPU有很多原因 - 我目前的机器是使用更旧处理器的备份,因为我的另一台机器有点笨拙)。我仍然会检查编译器实际生成的代码 - 完全有可能你的内在函数与编译器已经完成的几乎相同,因此“没有区别” - 我已经不止一次看到 gcc 和 clang 和 icc相当不错。
-
明天我用生成汇编代码的标志编译程序,我将看到它是如何工作的以及我的编译器如何翻译这个内在的。也许它会解决我的问题。
-
我编译了代码,我看到了汇编文件。 Intrisic 翻译得很好。但我还是不知道是什么问题。
标签: c++ intrinsics xeon-phi