在英特爾(R) 奔騰(R) M 處理器上,跨越快取線邊界的未對齊訪問會導致懲罰。“數據快取單元”(DCU) 拆分是跨越 64 位元組快取線邊界的記憶體訪問。未對齊的訪問可能導致 DCU 拆分,並導致奔騰 M 處理器暫停。
某些演算法(如視訊編解碼中的“運動估計”與“運動補償”演算法)天生傾向於導致頻繁發生未對齊的引用。在某些情況下,能減少未對齊引用的替代性編碼策略實際需要的時鐘週期總數可能會更多。
在以下情況中,此細節具有實質性意義:
計數器的商【未對齊的數據記憶體引用/數據記憶體引用(所有)】不佳。值 0.00 應視為良好,值 0.002 應視為不佳。
如果可能,在記憶體中對齊數據。
確保數據正確對齊。如果演算法天生具有未對齊的數據引用,並且需要訪問數據許多次,請將未對齊的數據複製到對齊的位置,並在對齊的數據上操作。此外,請避免將 80 位(浮點)值儲存到未對齊的位置。(請注意,對於某些編譯器,在堆疊上儲存 64 位數據可能會導致未對齊的引用)。
如果無法在記憶體中對齊數據,請考慮分多個步驟讀取數據,強制實現對齊。
如果無法在記憶體中對齊數據,請考慮分多個步驟讀取數據,並使用 SHIFT 與 OR 運算,以避免 DCU 快取線拆分懲罰。例如,假設需要讀取地址 [62-69](跨越地址 63 與 64 之間的 DCU 快取線邊界)。假設將這些值是 {v7 v6 v5 v4 v3 v2 v1 v0}。我們不需要“傻傻地”讀取這 8 個位元組,並付出遭受 DCU 快取線拆分懲罰的代價,而可以讀取兩個對齊的地址:r0=[56-63] 與 r1=[64-71]。現在,這兩個值分別是:r1 = {s1 s0 v7 v6 v5 v4 v3 v2};r0 = {v1 v0 t5 t4 t3 t2 t1 t0}。此時,我們可以將 r0 右移 8*6 位,得到 r0={0 0 0 0 0 0 v1 v0},將 r1 左移 8*2 位,得到 r1={v7 v6 v5 v4 v3 v2 0 0}。接著,我們對 r1 與 r2 執行 OR 運算,得到 {v7 v6 v5 v4 v3 v2 v1 v0}。這樣在不用遭受未對齊懲罰的情況下我們便讀取了這 8 個位元組(不過請注意,避免未對齊花費了 2 個 MOV、2 個 SHIFT 及 1 個 OR)。
確保程式碼正確對齊。
如果使用匯編程式碼編寫:
同 16 位元組邊界相距不足八個位元組時,循環入口標籤應該採用 16 位元組對齊方式。
跟在條件分支之後的標籤不需要對齊。
同 16 位元組邊界相距不足八位元組時,跟在無條件分支或函式呼叫之後的標籤應該採用 16 位元組對齊方式。
如果使用更高級的語言編寫:
使用將確保產生的程式碼滿足以上規則的編譯器。
在奔騰 M 處理器上,避免使用執行週期小於 2 的循環。緊湊循環的目標應該對齊 16 位元組邊界,以最大限度使用將獲取的指令。在奔騰 M 處理器上,可以限制可用於執行的指令數,從而限制每個週期失效的指令數。建議將關鍵的循環入口放在快取線邊界上。此外,還應展開執行時間不足 2 個週期的循環。