我注意到有時MSVC 2010根本沒有重新排序SSE指令。因爲編譯器處理的最好,我認爲我不必關心循環內部的指令順序,這似乎並不是這種情況。SSE微優化指令訂單
我應該怎麼想?什麼決定最佳指令順序?我知道一些指令比其他指令具有更高的延遲,並且某些指令可以在CPU級別上並行/異步運行。在上下文中哪些指標是相關的?我可以在哪裏找到它們?
我知道我可以避免通過分析這個問題,但是這樣的廓線儀價格昂貴(VTune™可視化XE)和我想知道它背後的理論,而不僅僅是emperical結果。
另外我應該關心軟件預取(_mm_prefetch
),或者我可以假設CPU會比我做得更好嗎?
可以說我有以下功能。我應該交錯一些指示嗎?我應該在溪流前做商店,按順序完成所有的裝載,然後進行計算,等等......?我是否需要考慮USWC與非USWC,以及時間還是非時間?
auto cur128 = reinterpret_cast<__m128i*>(cur);
auto prev128 = reinterpret_cast<const __m128i*>(prev);
auto dest128 = reinterpret_cast<__m128i*>(dest;
auto end = cur128 + count/16;
while(cur128 != end)
{
auto xmm0 = _mm_add_epi8(_mm_load_si128(cur128+0), _mm_load_si128(prev128+0));
auto xmm1 = _mm_add_epi8(_mm_load_si128(cur128+1), _mm_load_si128(prev128+1));
auto xmm2 = _mm_add_epi8(_mm_load_si128(cur128+2), _mm_load_si128(prev128+2));
auto xmm3 = _mm_add_epi8(_mm_load_si128(cur128+3), _mm_load_si128(prev128+3));
// dest128 is USWC memory
_mm_stream_si128(dest128+0, xmm0);
_mm_stream_si128(dest128+1, xmm1);
_mm_stream_si128(dest128+2, xmm2);;
_mm_stream_si128(dest128+3, xmm3);
// cur128 is temporal, and will be used next time, which is why I choose store over stream
_mm_store_si128 (cur128+0, xmm0);
_mm_store_si128 (cur128+1, xmm1);
_mm_store_si128 (cur128+2, xmm2);
_mm_store_si128 (cur128+3, xmm3);
cur128 += 4;
dest128 += 4;
prev128 += 4;
}
std::swap(cur, prev);
我認爲這個問題的答案必須是在測量試驗。儘管x86已經有[OOE](http://en.wikipedia.org/wiki/Out-of-order_execution)很長一段時間了,但無論排序如何,它都可以很好地處理這種情況。 – Flexo
測試總是最好的。但是在這種情況下,它需要一個相當昂貴的分析器,例如, VTune XE。我想更多地瞭解它背後的理論,而不是實證結果。 OOE走多遠?這是內存延遲還是指令延遲?如果重新訂購,OOE是否照顧可以並行運行的指令? – ronag
你可以發佈這個發佈版本的彙編程序輸出嗎?看看編譯器用這個做什麼會很有趣。 – Skizz