編譯過程中的並行性優化(三):軟件流水線化與SIMD技術

浙江大學《編譯原理》課程報告

上一篇:
編譯過程中的並行性優化(二):基本塊與全局代碼調度算法

軟件流水線化

軟件流水線化也是一種重要的指令調度技術,就像硬件流水線的指令一樣,它通過並行執行來自不同循環體的指令來加快循環程序的執行速度, 在前一個循環體未結束前啓動下一個新的循環體,來達成循環體時間上的並行性。相比於簡單的展開循環(在提高性能的同時會導致代碼的膨脹),軟件流水線提供了一個方便的優化方法,能夠在優化資源使用的同時保持代碼的簡潔。

對於循環之間沒有數據依賴的 do-all 循環,我們可以用一個簡單的對比來說明軟件流水線同簡單循環展開的不同,下圖爲簡單的循環展開:

在這裏插入圖片描述

軟件流水線化通過將循環展開調度後中重複的部分進行循環,完成流水線。下圖爲軟件流水線化的結果:

在這裏插入圖片描述

在開始階段(1-6行)用來填充流水線的指令序列被稱爲序言;在穩定循環的部分(7-8行)被稱爲穩定狀態;用來排空流水線的指令序列(9-14行)稱爲尾聲

在軟件流水中,相鄰循環體的啓動時間間隔稱爲啓動間距。在軟件流水中再次應用循環展開,使同一時刻可以運行多個循環,可以使軟件流水實現分數值的啓動間距,同時基於展開的優化技術可以降低程序的資源需求和關鍵路徑的長度。但是,循環展開也會引起代碼量增長和寄存器需求增大,代碼量的增長會導致緩存的性能變差,寄存器需求的增大則有可能使軟件流水失敗。因此,軟件流水的核心問題之一就是展開因子的確定。

對於各個迭代之間的存在數據依賴關係的循環,也稱 do-access 循環,軟件流水線化也可以起到一定的效果:

在這裏插入圖片描述

SIMD

SIMD 擴展指令允許將原來需要多次裝載的內存中地址連續的數據一次性裝載到向量寄存器中,通過一條 SIMD 擴展指令實現對 SIMD 向量寄存器中所有數據元素的並行處理;這種執行方式非常適合於處理計算密集、數據相關性少的音視頻解碼等多媒體程序。

爲了高效利用SIMD擴展部件的特性,需要讓編譯器分析串行程序中控制流和數據流的特徵,識別程序中可以向量執行的部分,將標量語句自動轉換爲相應的SIMD 向量語句。SIMD 自動向量化編譯流程大致可分爲3部分,分別是發掘、優化和代碼生成:

  • 發掘:識別生成出 SIMD 指令,同時解決控制依賴對發掘的影響。SIMD 擴展部件可在不同的粒度進行識別向量化,包括面向基本塊內向量化、面向最內層循環或者循環嵌套的向量化以及面向函數級別的向量化。
  • 優化:首先減小輔助指令的開銷,同時考慮數據局部性、寄存器重用等工作。由於部分體系結構的 SIMD 指令只能從內存中存取連續對齊的數據,因此當程序中存在不對齊或不連續內存引用時需要通過移位或者重組等輔助指令才能組成向量。減少輔助指令的數量和提高輔助指令的效率,是增加程序 SIMD 向量化收益的關鍵問題。
  • 代碼生成:考慮平臺支持哪些數據類型和向量運算。直接面向特定平臺的 SIMD 向量化代碼生成存在許多不足,通常分階段並行編譯優化和虛擬向量是解決面向多平臺向量化的兩個方法。

我的GIS/CS學習筆記:https://github.com/yunwei37/myClassNotes
<一個浙大GIS/CS小白的課程學習筆記 >


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章