【发布时间】:2016-04-19 09:18:09
【问题描述】:
我的笔记本电脑 CPU 仅支持 AVX(高级矢量扩展),但不支持 AVX2。对于 AVX,128 位 xmm* 寄存器已经扩展到 256 位 ymm* 寄存器以进行浮点运算。但是,我测试过所有版本的 Visual Studio(从 2010 年到 2015 年)在 /arch:AVX 优化下不使用 ymm* 寄存器,尽管它们在 /arch:AVX2 优化下使用。
下面展示了一个简单的 for 循环的反汇编。该程序在发布版本中使用 /arch:AVX 编译,所有优化选项都打开。
float a[10000], b[10000], c[10000];
for (int x = 0; x < 10000; x++)
1000988F xor eax,eax
10009891 mov dword ptr [ebp-9C8Ch],ecx
c[x] = (a[x] + b[x])*b[x];
10009897 vmovups xmm1,xmmword ptr c[eax]
100098A0 vaddps xmm0,xmm1,xmmword ptr c[eax]
100098A9 vmulps xmm0,xmm0,xmm1
100098AD vmovups xmmword ptr c[eax],xmm0
100098B6 vmovups xmm1,xmmword ptr [ebp+eax-9C78h]
100098BF vaddps xmm0,xmm1,xmmword ptr [ebp+eax-9C78h]
100098C8 vmulps xmm0,xmm0,xmm1
100098CC vmovups xmmword ptr [ebp+eax-9C78h],xmm0
100098D5 add eax,20h
100098D8 cmp eax,9C40h
100098DD jl ComputeTempo+67h (10009897h)
const int winpts = (int)(window_size*sr+0.5);
100098DF vxorps xmm1,xmm1,xmm1
100098E3 vcvtsi2ss xmm1,xmm1,ecx
我还测试了我可以使用 ymm* 寄存器来进一步加速我的程序而不会崩溃。我使用 IMM 内在函数来做到这一点,例如_mm256_mul_ps。
任何微软编译器开发人员可以给出解释吗?或者这可能是 Visual Studio 给出的代码比 gcc/g++ 编译器慢的原因之一?
=============已编辑==============
原因是在 32 位机器上运行 32 位操作系统和在 64 位机器上运行 32 位操作系统之间存在一些差异。在后一种情况下,某些操作系统可能不知道 ymm* 寄存器的存在,因此在上下文切换期间不会正确保留上半部分寄存器。因此,如果在 64 位机器上的 32 位操作系统上使用 ymm* 寄存器,如果发生上下文切换,如果另一个程序也在使用 ymm* 寄存器,则上半部分寄存器可能会静默损坏。在这种情况下,Visual Studio 有点保守。
【问题讨论】:
-
您是否尝试过编译器知道数组是 32B 对齐的循环?我注意到它使用了未对齐的加载/存储指令。此外,AMD CPU 使用 256b AVX 代码比使用 128b AVX 代码做得更差,尤其是。 Piledriver 对 256b 商店有很大的问题。因此,如果您没有告诉编译器针对特定的微架构进行优化,那么 128b 向量“更安全”。
-
我在 MSVC 2015 中使用
cl /c /O2 /arch:AVX测试了 voidvoid foo(float *a, float *b, float *c) { for(int i=0; i<10000; i++) c[i] = (a[i]+b[i])*b[i]; },它使用了ymm。不知道你遇到了什么问题。 -
@PeterCordes,在 AVX 中使用未对齐的加载指令不会受到任何惩罚。内存不是 32B 对齐的,但 Clang 和 MSVC 都不会为此调整(但 GCC 和 ICC 会)。
-
顺便说一句,
__restrict(void foo(float * __restrict a, float * __restrict b, float * __restrict c) for (int i = 0; i < 10000; i++) c[i] = (a[i] + b[i])*b[i]; }在这种情况下对 MSVC 没有影响,但对 Clang 和 GCC 有很大影响。 -
我发现了问题所在。您正在 32 位模式下编译。 Visual Studio 默认为 32 位模式。
标签: c++ visual-studio optimization visual-studio-2015 avx