MSVC编译器支持AVX512自动向量化

MSVC编译器支持AVX512自动向量化

作者:BlogUpdater |  时间:2020-02-29 |  浏览:5781 |  评论已关闭 条评论

蝎子
从Visual Studio 2019 v16.3开始,我们在MSVC编译器中的自动向量化添加了AVX-512指令集的支持。这篇文章主要展示了一些例子来帮助开发者如何在他们的项目中启用这一特性。

什么是自动向量?
MSVC编译器的的自动向量会分析用户代码中的循环部分,并为向量目标生成向量化的代码,来提升灵活性和运行时性能。先看看下面的代码片段:

举个例子,如果我使用[cl.exe /O2 /fp:fast /arch:AVX2]面向AVX2编译上面的代码,我会得到如下的汇编代码。

在上面汇编代码的第11~15行是使用了[ymm]寄存器的向量化循环。第16~21行则计算向量化循环的向量值的标量值之和。请注意,在向量循环中的迭代数量仅仅是标量循环的1/8,这意味着我们得到一次性能提升。

什么是AVX-512

Intel于2008年3月首次提出AVX指令集,它是x86 SSE指令集的扩展版本,可以说将运行效率提升了一倍。它的升级版AVX2支持256位宽操作并引入FMA指令集,而最新的AVX-512实际上可以认为是AVX3,这个指令集将位宽操作提升到了512位。
AVX-512是Intel引入的一套处理器扩展,旨在通过扩展向量到512位宽来强化向量计算,将向量寄存器增加了一倍,并引入了[element-wise operation masking]特性。
你可以通过测试[__isa_available]变量的值来判断AVX-512的支持情况,如果这个值大于等于6,则表示AVX-512得到了支持。同时,这表示了对F(Foundational)指令和VL, BW, DQ和CD扩展中的指令支持。这些指令借助于额外的AVX-512寄存器来添加了额外的整数向量操作,128位宽和256位宽操作,以及支持标量存储的地址冲突检测。
这些指令和下面描述的被编译开关[/arch:AVX512]启用的指令相同。这些扩展在所有支持AVX-512的处理器上可用。有关更多关于AVX-512和Visual Studio相关的文章,大家可以参考下列两篇文章:
> Microsoft Visual Studio 2017 Supports Intel® AVX-512
> Accelerating Compute-Intensive Workloads with Intel® AVX-512

如何启用AVX-512向量化
[/arch:AVS512]编译开关用来启用AVX-512支持,包括自动向量化。通过这个开关,自动向量器可以通过AVX-512中的F, VL, BW, DQ和CD扩展来向量化一个循环。

以下是将AVX-512向量化特性编译到你的应用程序中的步骤
> 在Visual Studio IDE中,你可以在[Property Pages > C/C++ > Command Line > Additional Options]中添加编译开关[/arch:AVX512],或者可以在工程属性页面选择[Advanced Vector Extension 512],配置路径为:[Project Properties > Configuration Properties > C/C++ > Code Generation > Enable Enhanced Instruction Set > Advanced Vector Extension 512 (/arch:AVX512)]。第二种方法在Visual Studio 2019 v16.4版本中可用。
> 如果你在命令行中使用cl.exe,则可以在/link选项中添加[/arch:AVX512]编译开关。

如果我再一次使用[cl.exe /O2 /fp:fast /arch:AVX512]来编译前面的例子代码,则我会得到下面的启用了AVX-512的汇编代码。

在上面的汇编代码中,第7~11行是向量循环。请注意,循环借助了[zmm]寄存器来实现了向量化,而不是使用[ymm]寄存器。通过[zmmx]寄存器的扩展位宽,AVX-512的向量循环的迭代数量只有AVX2版本的一半。

总结
似乎你开发的应用程序和AVX-512的距离还挺远的?其实不然,通过MSVC编译器中对AVX-512扩展越来越丰富的支持,咱们就可以轻松在应用程序中启用AVX-512扩展,显著的提升运行效率。

我们还是大胆地拥抱C++这支性能怪兽吧。

标签:

评论已关闭。