我试图在我的编译器(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).
vmovdqu ymm1,ymmword ptr [input2] vpaddw ymm1,ymm1,ymmword ptr [rbp] vmovdqu ymmword ptr [output2],ymm1
我不想重写我的代码来使用内在函数,但是:将它编写为循环更加自然,与旧的(仅限SSE)处理器兼容,并具有其他优点.
那么如何调整我的示例以使编译器能够以AVX2方式对其进行矢量化?