c – 为什么MSVC的自动矢量化不使用AVX2?

前端之家收集整理的这篇文章主要介绍了c – 为什么MSVC的自动矢量化不使用AVX2?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在我的编译器(Microsoft Visual Studio 2013)中使用矢量化.我面临的一个问题是它不想使用AVX2.在研究这个问题时,我构建了以下示例,它计算了16个数字的总和,每个数字为16位.
int16_t input1[16] = {0};
int16_t input2[16] = {0};
... // fill the arrays with some data

// Calculate the sum using a loop
int16_t output1[16] = {0};
for (int x = 0; x < 16; x++){
    output1[x] = input1[x] + input2[x];
}

编译器将此代码矢量化,但仅限于SSE指令:

vmovdqu  xmm1,xmmword ptr [rbp+rax]
lea      rax,[rax+10h]
vpaddw   xmm1,xmm1,xmmword ptr [rbp+rax+10h]
vmovdqu  xmmword ptr [rbp+rax+30h],xmm1
dec      rcx
jne      main+0b0h

为了确保编译器具有生成AVX2代码的选项,我编写了如下相同的计算:

// Calculate the sum using one AVX2 instruction
int16_t output2[16] = {0};
__m256i in1 = _mm256_loadu_si256((__m256i*)input1);
__m256i in2 = _mm256_loadu_si256((__m256i*)input2);
__m256i out2 = _mm256_add_epi16(in1,in2);
_mm256_storeu_si256((__m256i*)output2,out2);

我看到代码的两部分是等价的(也就是说,output11在执行后等于output2).

它为代码的第二部分输出AVX2指令:

vmovdqu  ymm1,ymmword ptr [input2]
vpaddw   ymm1,ymm1,ymmword ptr [rbp]
vmovdqu  ymmword ptr [output2],ymm1

我不想重写我的代码来使用内在函数,但是:将它编写为循环更加自然,与旧的(仅限SSE)处理器兼容,并具有其他优点.

那么如何调整我的示例以使编译器能够以AVX2方式对其进行矢量化?

解决方法

在进行浮点运算时,Visual Studio可以轻松生成AVX2代码.我想这足以宣称“VS2013支持AVX2”.

但是,无论我做了什么,VS2013都没有生成用于整数计算的AVX2代码(int16_t和int32_t都没有工作),所以我猜这根本不受支持(gcc为版本4.8.2的代码生成AVX2;不确定关于早期版本).

如果我必须对int32_t进行计算,我可以考虑将它们转换为浮动和返回.但是,因为我使用int16_t,所以没有用.

猜你在找的C&C++相关文章