gpt4 book ai didi

c - 英特尔至强融核使用的内在函数是否比自动矢量化获得更好的性能?

转载 作者:太空宇宙 更新时间:2023-11-04 07:17:01 24 4
gpt4 key购买 nike

Intel Xeon Phi 提供使用“IMCI”指令集,
我用它来做 "c = a*b",像这样:

float* x = (float*) _mm_malloc(N*sizeof(float), ALIGNMENT) ;
float* y = (float*) _mm_malloc(N*sizeof(float), ALIGNMENT) ;
float z[N];
_Cilk_for(size_t i = 0; i < N; i+=16)
{
__m512 x_1Vec = _mm512_load_ps(x+i);
__m512 y_1Vec = _mm512_load_ps(y+i);

__m512 ans = _mm512_mul_ps(x_1Vec, y_1Vec);
_mm512_store_pd(z+i,ans);

}

然后测试它的性能,当N SIZE为1048576时,
它需要成本 0.083317 Sec ,我想比较自动矢量化的性能
所以其他版本的代码是这样的:

_Cilk_for(size_t i = 0; i < N; i++)
z[i] = x[i] * y[i];

这个版本花费 0.025475 秒(但有时花费 0.002285 或更少,我不知道为什么?)
如果我将 _Cilk_for 更改为 #pragma omp parallel for,性能会很差。

所以,如果答案是这样的,为什么我们需要使用内部函数?
我有没有哪里出错了?
有人可以给我一些好的建议来优化代码吗?

最佳答案

由于各种错误,测量结果意义不大。

  • 代码将 16 个 float 存储为 8 个 double 。 _mm512_store_pd 应该是 _mm512_store_ps
  • 代码在地址为 z+i 的未对齐位置上使用 _mm512_store_...,这可能会导致段错误。使用 __declspec(align(64)) 来解决这个问题。
  • 数组 x 和 y 没有初始化。这有引入随机数的非正规值的风险,这可能会影响性能。 (我不确定这是否是 Intel Xeon Phi 的问题)。
  • 没有证据表明使用了 z,因此优化器可能会删除计算。我认为这里不是这种情况,但是像这样的微不足道的基准测试是有风险的。此外,在堆栈上分配大型数组有堆栈溢出的风险。
  • 示例的单次运行可能是一个糟糕的基准测试,因为时间可能主要由 _Cilk_for 的 fork/join 开销支配。假设有 120 个 Cilk worker(60 个 4 路线程内核的默认值),每个 worker 只有大约 1048576/120/16 = ~546 次迭代。时钟速率超过 1 GHz,这不会花很长时间。事实上,循环中的工作是如此之小,以至于一些 worker 很可能永远没有机会窃取工作。这可能解释了为什么 _Cilk_for 跑得比 OpenMP 快。在 OpenMP 中,所有线程都必须参与 fork/join 才能完成并行区域。

如果编写测试是为了纠正所有错误,那么它本质上就是在一个大数组上计算 z[:] = x[:]*y[:]。由于 Intel(R) Xeon Phi(TM) 上的宽 vector 单元,这成为对内存/高速缓存带宽的测试,而不是 ALU 速度,因为 ALU 完全有能力超过内存带宽。

内在函数对于不能表示为并行/simd 循环的事物很有用,通常是需要奇特排列的事物。例如,我使用内在函数来做一个 16 元素的 prefix-sum operation在 MIC 上(如果我没记错的话只有 6 条指令)。

关于c - 英特尔至强融核使用的内在函数是否比自动矢量化获得更好的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23757939/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com