2017-01-24 47 views
10

這似乎是一個recurring problem許多英特爾處理器(除非我錯了,直到Skylake)在將AVX-256指令與SSE指令混合使用時表現不佳。爲什麼SSE指令保留YMM寄存器的高128位?

根據Intel's documentation,這是由於SSE指令被定義爲保留YMM寄存器的高128位,所以爲了能夠通過不使用AVX數據路徑的高128位來節省功耗,CPU在執行SSE代碼時將這些位存儲起來,並在輸入AVX代碼時重新加載它們,存儲和加載代價很高。

但是,我找不到任何明顯的理由或解釋爲什麼SSE指令需要保留這些高128位。通過始終清除YMM寄存器的高128位而不是保留它們,相應的128位VEX指令(使用該指令可以避免性能損失)。在我看來,當Intel定義AVX體系結構,包括將XMM寄存器擴展到YMM寄存器時,他們可能已經簡單地定義了SSE指令也會清除高128位。顯然,由於YMM寄存器是新的,因此可能沒有遺留的代碼會依賴SSE指令來保存這些位,而且在我看來,英特爾可能已經很容易地看到了這一點。

因此,英特爾如何定義SSE指令以保留YMM寄存器的高128位?它有用嗎?

+8

Agner Fog在一個獲得英特爾迴應的問題中有一些洞見:https://software.intel.com/zh-cn/forums/intel-isa-extensions/topic/301853 –

+0

@MichaelPetch:Great find! – Dolda2000

回答

10

爲了移動現場的外部資源,我從the link Michael provided in the comments中提取了相關段落。

所有學分都發給他。
該鏈接指向Agner Fog在英特爾論壇上提出的非常類似的問題。

[霧在輸入反應Intel的答案]如果我理解你的權利,你決定了它必須有所有128位指令兩個版本,以避免 破壞YMM上部在中斷使用傳統XMM指令調用設備驅動程序的情況下注冊。

英特爾擔心,通過使傳統SSE指令歸零XMM上部註冊的ISR將現在突然 影響新YMM寄存器。
如果不支持保存新的YMM上下文,這將使得在任何 的情況下都無法使用AVX。

但是Fog並沒有完全滿意,並指出只需使用AVX感知編譯器重新編譯驅動程序(以便使用VEX指令)就會產生相同的結果。

英特爾回覆說他們的目標是避免強迫現有軟件重寫 。

我們不可能迫使業界重寫/修復所有現有的驅動程序(例如使用XSAVE),也無法保證它們能夠成功完成。例如,考慮到從32位到64位操作系統的過渡,這個行業仍然需要經歷的痛苦!我們來自操作系統供應商的反饋也阻止了向ISR服務增加開銷,從而在每個中斷上添加狀態管理開銷。我們不希望在通常不使用寬向量的行業中造成這些成本。

通過具有指示兩個版本,就可以實現在驅動AVX支持像它一直是FPU/SSE:

給出的例子是類似目前的情形,其中一環 - 0驅動程序(ISR)供應商嘗試使用浮點狀態,或在某些庫中意外鏈接到不在Ring-0上自動管理該上下文的操作系統。這是錯誤的一個衆所周知的來源,我可以建議只有以下:

  • 在這些操作系統,驅動程序開發人員使用浮點或AVX

  • 驅動程序開發人員,應鼓勵禁用氣餒驅動程序驗證過程中的硬件功能(如AVX狀態可以由司機環0到XSETBV()

+1

如果我正確閱讀Agner的評論,那麼額外複雜性的原因是由於Windows的64位調用約定「Windows 64位的ABI爲 Windows指定寄存器XMM6-XMM15具有被調用保存狀態」並且「只是爲了與現有的x64 Windows設備驅動程序兼容,通過迫使微軟實施我上面提到的懶惰保存解決方案,「這是微軟的錯。 –

+2

@Zboson我同意。隨着微軟的事情倒退:硬件必須適應軟件。無論如何,隨意編輯答案,這是一個社區維基,你的評論是一個很好的附加組件:) –

0

背景被禁用:在作出決定早做KeSaveFloatingP ointState在Windows x64上不做任何事情,並且即使在驅動程序中也允許使用XMM寄存器而無需額外的保存/恢復調用。顯然這些驅動程序不會知道AVX或YMM寄存器。