我有一个计算产生一个系数向量,并返回该向量的点积与从大数组中取得的数据向量。为了加快速度,我使用AVX2 SIMD内在函数一次为8个向量执行此操作。问题是大部分时间最终被聚合操作消耗得到点积的数据。
我尝试了不同的方法来实现聚集,内在似乎效果最好。我非常感谢有关加快这项工作的一些建议。
这是一幅草图:
__m256 Compute(__m256 input)
{
__m256 coefficients[56] = ComputeCoefficients(input);
__m256i indices = ComputeIndices(input);
__m256 sum = _mm256_setzero_ps();
for (size_t i = 0; i != 56; ++i)
{
__m256 data = _mm256_i32gather_ps(bigArray + i, indices, sizeof(float)); //
sum = _m256_fmadd_ps(coefficients[i], data, sum);
}
return sum;
}
答案 0 :(得分:1)
我首先要确保您使用的是最新的英特尔处理器。英特尔已投入大量工程来改进收集指令。
这就是说,这并不神奇。如果有缓存未命中,您将为它们付出代价。
我会尝试在没有SIMD指令的情况下编写相同的代码。它的速度大致相同吗?如果是,那么您的内存访问受限制的可能性很大。矢量化很好地解决了计算限制,以及以矢量大小为单位编写和存储数据,但即使在原则上,也不能期望对随机访问和缓存问题的约束问题有很大的帮助。 / p>
您的代码反复拨打VPGATHERDPS
。根据Agner Fog的说法,该指令的延迟为12个周期,每4个周期一个指令的吞吐量。当然,延迟是最好的情况,缓存未命中会增加延迟。
您应该对代码进行基准测试,并确保每个循环迭代接近4个周期。主循环应该在大约300个循环中完成,并且所有事情都说得很快。
你没有告诉我们很多关于你的问题,但我们可以猜测它比300个周期慢得多。如果是这样,那么你可能有缓存问题。如果您的表很大并且您随机访问它,那么这是一个难题。如果您需要更好的性能,可能需要重新设计问题。