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

标签 c++ c visual-studio-2013 vectorization 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_tint32_t 都不起作用),所以我猜这是不支持的完全没有(gcc 在 4.8.2 版为我的代码生成 AVX2;不确定早期版本)。

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

关于c++ - 为什么 MSVC 的自动矢量化不使用 AVX2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26864623/

相关文章:

c++ - 在线程之间解析 OpenCV 帧

asp.net - Visual Studio : Handling Typescript and LESS project files (with TFS Build)

c++ - QLineEdit : setValidator for 4bytes unsigned Integer not working

c++ - 析构函数调用以前从未构造过的对象

c++ - 如何找到未初始化的堆栈变量

c - 读取/接收线程安全 (MSG_PEEK)

c - 在C中返回值后如何回调函数

c - fgets 的问题

c++ - 编译具有不同 header 名称的 C++ 文件

c++ - boost.Hana 中的 when<> 特性如何工作?