AVX-512在MSVC中的自动矢量化

Visual Studio 2019版本16.3 我们为MSVC编译器的自动矢量器添加了AVX-512支持。这篇文章将展示一些例子,并帮助您在项目中启用它。

null

什么是自动矢量器?

编译器的 自动矢量器 分析用户源代码中的循环,并在可行和有利的情况下为向量化目标生成向量化代码。

static const int length = 1024 * 8;
static float a[length];
float scalarAverage() {
    float sum = 0.0;
    for (uint32_t j = 0; j < _countof(a); ++j) {
        sum += a[j];
    }

    return sum / _countof(a);
}

例如,如果我使用 cl.exe/O2/fp:快速/arch:AVX2 针对AVX2,我得到以下程序集。第11-15行是使用ymm寄存器的矢量化循环。第16-21行用于计算标量值 总和 来自向量循环的向量值。请注意,向量循环的迭代次数仅为标量循环的1/8,这通常意味着性能的提高。

?scalarAverage@@YAMXZ (float __cdecl scalarAverage(void)):
00000000: push ebp
00000001: mov ebp,esp
00000003: and esp,0FFFFFFF0h
00000006: sub esp,10h
00000009: xor eax,eax
0000000B: vxorps xmm1,xmm1,xmm1
0000000F: vxorps xmm2,xmm2,xmm2
00000013: nop dword ptr [eax]
00000017: nop word ptr [eax+eax]
00000020: vaddps ymm1,ymm1,ymmword ptr ?a@@3PAMA[eax]
00000028: vaddps ymm2,ymm2,ymmword ptr ?a@@3PAMA[eax+20h]
00000030: add eax,40h
00000033: cmp eax,8000h
00000038: jb 00000020</span>
0000003A: vaddps ymm0,ymm2,ymm1
0000003E: vhaddps ymm0,ymm0,ymm0
00000042: vhaddps ymm1,ymm0,ymm0
00000046: vextractf128 xmm0,ymm1,1
0000004C: vaddps xmm0,xmm1,xmm0
00000050: vmovaps xmmword ptr [esp],xmm0</span>
00000055: fld dword ptr [esp]
00000058: fmul dword ptr [__real@39000000]
0000005E: vzeroupper
00000061: mov esp,ebp
00000063: pop ebp
00000064: ret

什么是AVX-512?

AVX-512是Intel推出的一系列处理器扩展,可增强 矢量化 通过将向量扩展到512位,将向量寄存器的数量增加一倍,并引入元素操作屏蔽。您可以使用可用变量isau检测对AVX-512的支持,如果找到对AVX-512的支持,该变量将为6或更大。这表示支持F(基本)指令,以及来自VL、BW、DQ和CD扩展的指令,这些扩展添加了额外的整数向量操作、128位和256位操作以及额外的AVX-512寄存器和掩蔽,以及用于检测与分散存储的地址冲突的指令。这些指令与 /arch:AVX512 如下所述。这些扩展在Windows官方支持的所有AVX-512处理器上都可用。关于AVX-512的更多信息可以在我们之前发布的以下博客文章中找到。

如何启用AVX-512矢量化?

/arch:AVX512 is 启用AVX-512支持的编译器开关,包括自动矢量化。使用此开关,自动矢量器可以使用AVX-512中的F、VL、BW、DQ和CD扩展指令对循环进行矢量化。

要在启用AVX-512矢量化的情况下构建应用程序,请执行以下操作:

  • 在VisualStudioIDE中,您可以添加标志/arch:AVX512 to 项目属性页> C/C++ >命令行>附加选项文本框或打开/arch:AVX512 by 选择高级向量扩展512遵循ProjtProjts>配置属性> C/C++ >代码生成>启用增强指令集>高级向量扩展512(/arch:AVX512). 第二种方法在VisualStudio2019版本16.4中提供。
  • 如果使用cl.exe从命令行编译,请添加标志/arch:AVX512 before 任何/链接选项。

如果我使用 cl.exe/O2/fp:快速/arch:AVX512 ,我将获得以下针对AVX-512的程序集。类似地,第7-11行是矢量化循环。注意,循环是用zmm寄存器而不是ymm寄存器矢量化的。随着zmmx寄存器宽度的扩大,AVX-512矢量循环的迭代次数仅为AVX2版本的一半。

?scalarAverage@@YAMXZ (float __cdecl scalarAverage(void)):
00000000: push ecx
00000001: vxorps xmm0,xmm0,xmm0
00000005: vxorps xmm1,xmm1,xmm1
00000009: xor eax,eax
0000000B: nop dword ptr [eax+eax]
00000010: vaddps zmm0,zmm0,zmmword ptr ?a@@3PAMA[eax]
0000001A: vaddps zmm1,zmm1,zmmword ptr ?a@@3PAMA[eax+40h]
00000024: sub eax,0FFFFFF80h
00000027: cmp eax,8000h
0000002C: jb 00000010
0000002E: vaddps zmm1,zmm0,zmm1
00000034: vextractf32x8 ymm0,zmm1,1
0000003B: vaddps ymm1,ymm0,ymm1
0000003F: vextractf32x4 xmm0,ymm1,1
00000046: vaddps xmm1,xmm0,xmm1
0000004A: vpsrldq xmm0,xmm1,8
0000004F: vaddps xmm1,xmm0,xmm1
00000053: vpsrldq xmm0,xmm1,4
00000058: vaddss xmm0,xmm0,xmm1
0000005C: vmovss dword ptr [esp],xmm0
00000061: fld dword ptr [esp]
00000064: fmul dword ptr [__real@39000000]
0000006A: vzeroupper
0000006D: pop ecx
0000006E: ret

闭幕词

对于这个版本,我们的目标是实现与/arch:AVX2 in 矢量化能力术语。在未来的版本中,我们还计划改进很多东西。例如,我们的下一个AVX-512改进将利用新的屏蔽指令。随后的更新将支持VL扩展中的嵌入式广播、分散、128位和256位AVX-512指令。

一如既往,我们希望听到您的反馈,并鼓励您 下载 Visual Studio 2019 尝试一下。如果您遇到任何问题或对我们有任何建议,请让我们通过 帮助>发送反馈>报告问题/建议功能 在Visual Studio IDE中,或通过 开发者社区 ,或 推特@visualc .

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享