我對MOVSD彙編指令有些困惑。我寫了一些計算一些矩陣乘法的數字代碼,只是使用普通的C代碼而沒有SSE內在函數。我甚至不包括用於編譯的SSE2內在函數的頭文件。但是當我檢查彙編輸出時,我看到:SSE指令MOVSD(擴展:x86,x86-64上的浮點標量和向量操作)
1)使用128位向量寄存器XMM; 2)調用SSE2指令MOVSD。
據我所知,MOVSD實質上是在單精度浮點運算。它只使用XMM寄存器的低64位並設置高64位0.但我只是不明白兩件事:
1)我從來沒有給編譯器提供任何使用SSE2的提示。另外,我使用GCC而不是intel編譯器。據我所知,英特爾編譯器會自動尋找向量化的機會,但GCC不會。那麼GCC如何知道使用MOVSD?或者,這個x86指令在SSE指令集之前就已經存在很久了,而SSE2中的_mm_load_sd()內部函數僅僅是爲了向標量計算使用XMM寄存器提供向後兼容性?
2)爲什麼編譯器不使用其他浮點寄存器,80位浮點堆棧或64位浮點寄存器?爲什麼它必須使用XMM寄存器(通過設置高64位0,並且實質上浪費了該存儲)? XMM是否提供更快的訪問?
順便說一下,我有關於SSE2的另一個問題。我只是看不到_mm_store_sd()和_mm_storel_sd()之間的區別。兩者都將較低的64位值存儲到一個地址。有什麼不同?性能差異?對齊差異?
謝謝。
更新1:
OKAY,很明顯當我第一次問這個問題,我缺乏關於如何管理着CPU浮點運算的一些基本知識。所以專家們傾向於認爲我的問題是無意義的。由於我沒有包含最短的樣本C代碼,人們可能會認爲這個問題也很模糊。在這裏,我將提供a review作爲答案,希望對於任何不清楚現代CPU浮點運算的人都會有所幫助。
在64位模式下,調用約定已經強制SSE寄存器用於浮點參數和返回值。由於SSE寄存器不是以堆棧的形式組織的,而且它們更多,因此編譯器更容易使用。有標量SSE指令。另外,有趣的是你擔心會浪費一半的空間 - 如果你完全不使用它們,*所有的*都會浪費;) – Jester
沒有64位浮點指針寄存器。只有80位浮點堆棧和XMM寄存器。 MOVSD指令是標量指令,而不是矢量指令,因此它的使用並不意味着自動矢量化。 –
那些不是浮點寄存器。 –