我正在尝试对执行大量迭代(超过300 000 000)的循环进行矢量化以获得一些计算时间:
uint16_t* samples = (uint16_t*)pixmap->samples;
Image image(pixmap->w, pixmap->h);
uint8_t *dest = (uint8_t*)image[0];
for (int x = 0; x < len; x++)
{
dest[x] = samples[x] & 0xFF;
}
但是qvec-report表示,由于1300的原因,它无法进行矢量化。
根据MSDN,原因1300是:
循环体包含无计算或非常少的计算。
实际上,我的循环体的计算量非常小,但由于迭代次数很多,所以仍然需要一些时间。
为什么在这种情况下不进行矢量化?是因为它不值得吗?如果是,为什么?
如果不是,有什么办法或任何技巧可以“逼迫”吗?
答案 0 :(得分:3)
基本上,循环体是如此简单,以至于编译它的效率更高,而不是矢量化它,因为矢量化的运行时成本将大于执行代码。
尝试强制它没有意义,因为编译器告诉你矢量化版本的效率低于非矢量化版本。如果向循环添加更多计算,编译器可能会选择对其进行矢量化。
答案 1 :(得分:3)
您可能会混淆自动矢量化程序(SSE / AVX)和自动并行程序(线程)。但这不是真正的问题,我怀疑:dest[x] = samples[x] & 0xFF
的确意味着dest[x] = static_cast<uint8_t>(static_cast<int>(samples[x]) & 0xFF)
。由于所有这些转换都有不同的宽度,因此很难找到等效的SSE代码。 SSE2允许您组织一个16x8或8x16位的128位寄存器,但这里混合使用8位和16位类型,以及32位字面值。