我有一个计算,产生一个系数向量,并返回这个向量的点积从一个大数组的数据向量。为了加快速度,我一次用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;
}发布于 2017-02-03 23:01:03
我首先要确保您使用的是最新的英特尔处理器。英特尔已经投入了大量的工程来改进集合指令。
话虽如此,它并不神奇。如果有缓存丢失,您将为此付出代价。
我会尝试在没有SIMD指令的情况下编写相同的代码。差不多一样的速度吗?如果是的话,那么你很有可能受到内存访问的限制。矢量化很好地解决了计算的局限性,并且可以用向量大小的单元来编写和存储数据,但是即使在原则上,它也不能帮助解决随机访问和缓存问题所限制的问题。
您的代码多次调用VPGATHERDPS。根据Agner的说法,这个指令的延迟时间为12个周期,每4个周期就有一个指令的吞吐量。当然,延迟是最好的情况,缓存丢失会增加延迟。
您应该对代码进行基准测试,并确保每次循环迭代接近4个周期。主循环应该在大约300个周期内完成,这是非常快的所有事情都说的。
你没有告诉我们很多关于你的问题,但我们可以猜测它比300个周期慢得多。如果是这样的话,那么您可能有缓存问题。如果您的表是大的,并且您是随机访问它,那么这是一个困难的问题。如果您需要更好的性能,您可能需要重新设计问题。
https://stackoverflow.com/questions/41499625
复制相似问题