使用 AVX 指令禁用 exp() 优化?
我正在使用 AVX 内在函数在 VC++ 中编写前馈网络。我通过 C# 中的 PInvoke 调用此代码。当调用计算大循环(包括函数 exp())的函数时,对于 160M 的循环大小,我的性能约为 1000 毫秒。一旦我调用任何使用 AVX 内在函数的函数,然后使用 exp(),对于相同的操作,我的性能就会下降到约 8000 毫秒。请注意,计算 exp() 的函数是标准 C,并且使用 AVX 内在函数的调用与正在处理的数据完全无关。某种标志在运行时某处被触发。
换句话说,
A(); // 1000ms calculates 160M exp()
B(); // completely unrelated but contains AVX
A(); // 8000ms
或者,奇怪的是,
C(); // contains 128 bit SSE SIMD expressions
A(); // 1000ms
我不知道这里可能发生什么机制,或者如何寻求解决方案。我使用的是 Intel 2500K cpu\Win 7. Express 版本的 VS。
谢谢。
I am writing a feed forward net in VC++ using AVX intrinsics. I am invoking this code via PInvoke in C#. My performance when calling a function that calculates a large loop including the function exp() is ~1000ms for a loopsize of 160M. As soon as I call any function that uses AVX intrinsics, and then subsequently use exp(), my performance drops to about ~8000ms for the same operation. Note that the function calculating the exp() is standard C, and the call that uses the AVX intrinsics can be completely unrelated in terms of data being processed. Some kind of flag is getting tripped somewhere at runtime.
In other words,
A(); // 1000ms calculates 160M exp()
B(); // completely unrelated but contains AVX
A(); // 8000ms
or, curiously,
C(); // contains 128 bit SSE SIMD expressions
A(); // 1000ms
I am lost as to what possible mechanism is going on here, or how to pursue a sol'n. I'm on an Intel 2500K cpu\Win 7. Express versions of VS.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您使用任何 AVX256 指令,“AVX 高位状态”将变为“脏”,如果您随后使用 SSE 指令(包括在 xmm 寄存器中执行的标量浮点),这会导致严重停顿。这在英特尔优化手册中有记录,您可以免费下载(如果你正在做这种工作):
您的例程
B( )
会弄脏 YMM 状态,因此A( )
中的 SSE 代码会停止。在B
和A
之间插入VZEROUPPER
指令可以避免该问题。If you use any AVX256 instruction, the "AVX upper state" becomes "dirty", which results in a large stall if you subsequently use SSE instructions (including scalar floating-point performed in the xmm registers). This is documented in the Intel Optimization Manual, which you can download for free (and is a must-read if you're doing this sort of work):
Your routine
B( )
dirties the YMM state, so the SSE code inA( )
stalls. Insert aVZEROUPPER
instruction betweenB
andA
to avoid the problem.