使用AVX指令禁用exp()优化?

Aro*_*ler 6 x86 avx visual-c++ exp

我正在使用AVX内在函数在VC++中编写一个前馈网络.我在C#中通过PInvoke调用此代码.调用计算包含函数exp()的大循环的函数时,我的性能对于160M的循环大小是~1000ms.一旦我调用任何使用AVX内在函数的函数,然后使用exp(),我的性能就会下降到大约~8000ms进行相同的操作.请注意,计算exp()的函数是标准C,并且使用AVX内在函数的调用在处理的数据方面可能完全不相关.某种标志在运行时会在某处绊倒.

换一种说法,

A(); // 1000ms calculates 160M exp() 
B(); // completely unrelated but contains AVX
A(); // 8000ms
Run Code Online (Sandbox Code Playgroud)

或者,奇怪的是,

C(); // contains 128 bit SSE SIMD expressions
A(); // 1000ms
Run Code Online (Sandbox Code Playgroud)

我很遗憾这里有什么可能的机制,或者如何追求一个解决方案.我在英特尔2500K cpu\Win 7. Express版本的VS.

谢谢.

Ste*_*non 10

如果使用任何AVX256指令,则"AVX上部状态"变为"脏",如果随后使用SSE指令(包括在xmm寄存器中执行的标量浮点),则会导致大的停顿.这在英特尔优化手册中有记录,您可以免费下载(如果您正在进行此类工作,则必须阅读):

AVX指令总是修改YMM寄存器的高位,而SSE指令不修改高位.从硬件角度来看,YMM寄存器集合的高位可以被认为是三种状态之一:

•清洁:YMM的所有高位均为零.这是处理器从RESET启动时的状态.

•已修改并保存到XSAVE区域YMM寄存器的高位内容与XSAVE区域中的已保存数据相匹配.执行XSAVE/XRSTOR后会发生这种情况.

•已修改和未保存:执行一条AVX指令(256位或128位)会修改目标YMM的高位.

只要处理器状态为"已修改且未保存",AVX/SSE转换惩罚就适用.使用VZEROUPPER将处理器状态移至"清理"并避免转换惩罚.

您的例程B( )会使YMM状态变脏,因此SSE代码会A( )停顿.插入VZEROUPPER之间的指令BA避免这些问题.