我一直試圖找出應用程序中的性能問題,并最終將其縮小到一個非常奇怪的問題。如果VZEROUPPER指令被注釋掉,則下面一段代碼在Skylake CPU(i5-6500)上運行速度慢6倍。我測試了Sandy Bridge和Ivy Bridge CPU,兩種版本都以相同的速度運行,有或沒有VZEROUPPER?,F在我VZEROUPPER對這個代碼有了一個相當好的想法,而且我認為當沒有VEX編碼指令并且沒有調用可能包含它們的任何函數時,它對這個代碼根本不重要。事實上它不支持其他支持AVX的CPU似乎支持這一點。英特爾?64和IA-32架構優化參考手冊中的表11-2也是如此那么發生了什么?我留下的唯一理論是,CPU中存在一個錯誤,它錯誤地觸發了“保存AVX寄存器的上半部分”程序,而不應該這樣做?;蛘咂渌恍┩瑯悠婀值臇|西。這是main.cpp:#include <immintrin.h>int slow_function( double i_a, double i_b, double i_c );int main(){ /* DAZ and FTZ, does not change anything here. */ _mm_setcsr( _mm_getcsr() | 0x8040 ); /* This instruction fixes performance. */ __asm__ __volatile__ ( "vzeroupper" : : : ); int r = 0; for( unsigned j = 0; j < 100000000; ++j ) { r |= slow_function( 0.84445079384884236262, -6.1000481519580951328, 5.0302160279288017364 ); } return r;}生成的代碼與gcc不同,但它顯示相同的問題。較舊版本的intel編譯器生成了另一個函數的變體,它也顯示了問題,但只有在main.cpp沒有使用intel編譯器構建時,因為它插入調用來初始化一些自己的庫,這可能最終會在VZEROUPPER某處做。當然,如果整個東西都是用AVX支持構建的,那么內在函數就會變成VEX編碼指令,也沒有問題。我已經嘗試perf在linux上分析代碼,并且大多數運行時通常依賴于1-2條指令,但并不總是相同的,具體取決于我所分析的代碼版本(gcc,clang,intel)??s短功能似乎會使性能差異逐漸消失,因此看起來幾條指令都會導致問題。
添加回答
舉報
0/150
提交
取消