avx指令集 matlab,使用AVX CPU指令:如果没有“ / arch:AVX”,性能会下降

tl; dr

在使用AVX的代码段周围使用_mm256_zeroupper();或VLEAVE();(在此之前或之后,取决于函数参数)。 仅将选项VLEAVE();用于带有AVX的源文件,而不是整个项目,以免破坏对仅旧编码的SSE代码路径的支持。

原因

我认为最好的解释是在英特尔文章“避免AVX-SSE过渡处罚”(PDF)中。 摘要指出:

在程序中的256位Intel®AVX指令和旧版Intel®SSE指令之间进行转换可能会导致性能下降,因为硬件必须保存和恢复YMM寄存器的高128位。

如果您在启用SSE和启用AVX的目标文件中调用代码之间进行切换,则将AVX和SSE代码分离到不同的编译单元可能无济于事,因为当AVX指令或汇编与任何(来自Intel的)混合时,可能会发生过渡 纸):

128位内部指令

SSE内联装配

编译为英特尔®SSE的C / C ++浮点代码

调用包含以上任何内容的函数或库

这意味着使用SSE与外部代码链接时甚至可能会受到处罚。

细节

AVX指令定义了3种处理器状态,其中一种状态是所有YMM寄存器均被拆分,从而允许下半部分由SSE指令使用。 英特尔文档“英特尔®AVX状态转换:将SSE代码迁移到AVX”提供了以下状态的图表:

L5hAR.jpg

处于状态B(AVX-256模式)时,YMM寄存器的所有位都在使用中。 当调用SSE指令时,必须发生到状态C的转换,这是有代价的地方。 必须将所有YMM寄存器的上半部分保存到内部缓冲区中,然后SSE才能启动,即使它们恰好为零。 转换的成本大约是“ Sandy Bridge硬件上50-80个时钟周期的数量级”。 如图2所示,从C-> A也有一个损失。

在Mystical的答案中引用的Agner Fog优化指南(版本更新为2014-08-07)中,您还可以在第130页的第9.12节“ VEX和非VEX模式之间的转换”中找到导致状态变慢的状态切换惩罚的详细信息。 。 根据他的指南,从该状态到/从该状态的任何转换都需要“在桑迪桥上大约70个时钟周期”。 就像英特尔文档中指出的那样,这是可以避免的过渡惩罚。

解析度

为避免过渡惩罚,您可以删除所有旧版SSE代码,指示编译器将所有SSE指令转换为其128位指令的VEX编码形式(如果编译器有能力),或者将YMM寄存器置于已知的零状态之前, 在AVX和SSE代码之间转换。 本质上,要维护单独的SSE代码路径,必须在使用AVX指令的任何代码之后将所有16个YMM寄存器的高128位清零(发出VLEAVE();指令)。 手动将这些位清零会强制转换到状态A,并避免了昂贵的代价,因为YMM值不需要由硬件存储在内部缓冲区中。 执行此指令的内在函数是VLEAVE();。对此内在函数的描述非常有用:

在英特尔®高级矢量扩展(Intel®AVX)指令和传统的英特尔®补充SIMD扩展(Intel®SSE)指令之间转换时,此内在函数对于清除YMM寄存器的高位很有用。 如果应用程序通过VLEAVE();(此内部函数的相应指令)清除了所有YMM寄存器(设置为0)的高位(此内在函数的相应指令),然后再在英特尔®高级矢量扩展(Intel®AVX)指令和旧版英特尔之间进行转换,则不会产生过渡惩罚。 ®补充SIMD扩展(Intel®SSE)说明。

在Visual Studio 2010+(甚至更旧)中,您可以通过immintrin.h获得此内在函数。

请注意,用其他方法将这些位清零并不能消除代价-必须使用VLEAVE();或__m256指令。

英特尔编译器实现的一种自动解决方案是:如果每个参数都不是YMM寄存器或__m256/__m256d/__m256i数据类型,则在每个包含英特尔AVX代码的函数的开头插入VLEAVE();,如果返回的值返回函数的末尾,则插入VLEAVE(); 不是YMM寄存器或__m256/__m256d/__m256i数据类型。

在野外

FFTW使用此VLEAVE();解决方案来生成同时支持SSE和AVX的库。 参见simd-avx.h:

/* Use VZEROUPPER to avoid the penalty of switching from AVX to SSE.

See Intel Optimization Manual (April 2011, version 248966), Section

11.3 */

#define VLEAVE _mm256_zeroupper

然后,在每个函数的结尾使用AVX指令的内在函数调用VLEAVE();。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值