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之间的指令B和A避免这些问题.
| 归档时间: |
|
| 查看次数: |
1774 次 |
| 最近记录: |