7

我正在尝试在我的编译器(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 方式对其进行矢量化呢?

4

1 回答 1

0

Visual Studio 在进行浮点运算时很容易生成 AVX2 代码。我想这足以声明“VS2013 支持 AVX2”。

但是,无论我做什么,VS2013 都没有为整数计算生成 AVX2 代码(也int16_t没有int32_t工作),所以我想这根本不支持(gcc 在 4.8.2 版本为我的代码生成 AVX2;不确定之前版本)。

如果我必须对 进行计算int32_t,我可以考虑将它们float来回转换。但是,由于我使用int16_t,它没有帮助。

于 2015-02-23T20:14:00.873 回答