Helium 技術(shù)講堂 | 循環(huán)緩沖區的使用
當人工智能 (AI) 下沉到各式各樣的應用當中,作為市場(chǎng)上最大量的物聯(lián)網(wǎng)設備也將被賦予智能性。Arm ? Helium? 技術(shù)正是為基于 Arm Cortex ? -M 處理器的設備帶來(lái)關(guān)鍵機器學(xué)習與數字信號處理的性能提升。
本文引用地址:http://dyxdggzs.com/article/202408/461970.htm在上周的 Helium 技術(shù)講堂中,我們與大家共同探討了復雜而又有趣的 交錯加載/存儲指令 。 今天,我們將一起聊聊與內存訪(fǎng)問(wèn)相關(guān)的內容。 若您想要了解如何高效利用 Helium,千萬(wàn)別錯過(guò)文末視頻,通過(guò) Arm 技術(shù)專(zhuān)家的實(shí)例演示,詳解 Helium 如何為端點(diǎn)設備引入更多智能。
Arm Helium 技術(shù)誕生的由來(lái)循環(huán)緩沖區的使用
作者:Arm 架構與技術(shù)部高級首席工程師 Fran?ois Botman
我們在為 Arm Cortex-M 處理器系列設計矢量擴展 (MVE) —— Arm Helium 技術(shù)時(shí),希望它能廣泛地適用于各種數字信號處理 (DSP) 的應用。 具備高效的數據計算能力只成功了一半,同樣重要的是具備在內存中訪(fǎng)問(wèn)和存儲這些數據的能力。
正如之前的文章內容所述,Helium 是一種四節拍矢量架構。將數據加載到矢量中的最直接的方法是連續加載操作(見(jiàn)圖一)。在每個(gè)節拍中,都從標量寄存器中指定的基址開(kāi)始依次訪(fǎng)問(wèn)內存。無(wú)論目標數據類(lèi)型如何(8、16 或 32 位),都可以通過(guò)充分利用總線(xiàn)寬度的訪(fǎng)問(wèn)來(lái)高效地執行這一操作,因為數據元素在內存和矢量中都是相鄰的,存儲操作也是如此。
圖一:連續加載操作
內存是一種稀缺資源,通常情況下,要盡可能緊湊地打包數據,使用可容納數據的最小數據類(lèi)型。不過(guò),在處理數據時(shí),可能需要更多的空間,以避免在計算的中間階段出現溢出。這可以作為一個(gè)獨立的拓寬指令來(lái)執行,但正如 本系列第一篇文章 所述,它存在時(shí)間跨越問(wèn)題(對于 8 到 32 位的擴展,將數據擴展到最后一節拍需要第一節拍的數據,而第一節拍的數據已不可用)。因此,擴展指令不能與其他指令重疊,否則會(huì )對性能產(chǎn)生不利影響。 相反,Helium 引入了改變大小的內存操作。數據可以作為單個(gè) 8、16 或 32 位訪(fǎng)問(wèn),針對每個(gè)節拍高效加載,并用零或符號擴展,以匹配所需的數據類(lèi)型。 在圖二的示例中,我們希望執行將每個(gè)矢量通道的 8 位加載擴展到 16 位。兩個(gè) 8 位數據樣本作為一個(gè) 16 位加載操作加載,每個(gè)樣本在寫(xiě)入矢量通道之前擴展到 16 位。同樣,對于存儲來(lái)說(shuō),數據可以截斷到所需的大小,實(shí)現高效存儲。
圖二:加載擴展
Helium 加載和存儲指令具有與 M 系列架構的其他部分相同的豐富的尋址模式集,支持預遞增或后遞增以及指針回寫(xiě)等功能。 這樣,在大多數情況下就不需要單獨進(jìn)行指針操作了。
DSP 應用通常在數據結構而非單個(gè)元素上運行。例如,立體聲音頻數據通常以左右數值交織流的形式存儲。同樣,圖像數據通常以紅、綠、藍、Alpha 交錯值的形式存儲。這是 上一篇文章 的主題內容,其中介紹了可以有效實(shí)現這一目標的結構化加載/存儲指令。
有時(shí),存儲在內存中的數據無(wú)法以便捷的方式構建以實(shí)現連續訪(fǎng)問(wèn)。在某些架構中,這實(shí)際上會(huì )阻礙代碼的矢量化。 Helium 通過(guò)“離散?聚合”操作解決了這一問(wèn)題。 這些操作將偏移矢量指向內存,這樣就可以用一條指令訪(fǎng)問(wèn)多個(gè)非連續地址(見(jiàn)圖三)。它們還能擴展或截斷所訪(fǎng)問(wèn)的數據。
圖三:匯總負載
“離散-聚合”操作是一種功能強大的指令,可為應用提供很大的靈活性。例如,它們幾乎是實(shí)現 FFT(快速傅里葉變換)不可或缺的工具;在這種算法中,第一個(gè)或最后一個(gè)蝴蝶階段的內存訪(fǎng)問(wèn)需要使用反位尋址執行。專(zhuān)用反位指令 (VBRSR) 生成反位尋址模式,供這些離散-聚合指令使用。為了提高性能,這些指令重疊執行,加載數據的效率遠遠超過(guò)同等序列的標量指令。而且,它們也更容易使用。雖然連續矢量訪(fǎng)問(wèn)能為規律模式提供更好的性能,但由于離散-聚合指令無(wú)法對數據布局做出假設,因此有多少個(gè)不同的元素,匯總加載指令就必須執行多少次單獨的訪(fǎng)問(wèn)。對于 8 位數據,訪(fǎng)問(wèn)次數可能多達 16 次,這就成了不斷加載的負載。
DSP 應用通常使用一種稱(chēng)為循環(huán)尋址的內存布局??梢园错樞蛟L(fǎng)問(wèn)元素,但最多只能訪(fǎng)問(wèn)配置的緩沖區大小,之后的訪(fǎng)問(wèn)會(huì )繞回到第一個(gè)元素(見(jiàn)圖四)。例如,從元素 N?1 開(kāi)始的四元素讀取操作將會(huì )訪(fǎng)問(wèn)元素 N?1, 0, 1, 2。
圖四:循環(huán)緩沖區示例
這在 DSP 應用中用途廣泛,包括在處理數據流后只需要前 N 個(gè)數據樣本時(shí)避免指針操作。在 FIR 濾波器中,最后 N 個(gè)數據樣本需要與一組系數相乘,才能產(chǎn)生所需的濾波器響應。當一個(gè)新的數據樣本到來(lái)時(shí),需要處理的是之前的 N?1 個(gè)樣本和新樣本,最舊的樣本不再使用。數據可以重新排列,使要處理的緩沖區總是按正確的順序包含元素,但這需要在開(kāi)始處理前將每個(gè)樣本復制到不同的位置,耗費大量資源。 如果使用循環(huán)緩沖區,就可以就地訪(fǎng)問(wèn)數據,必要時(shí)還可以繞回到開(kāi)頭,而且只需要寫(xiě)入一次就可以用最新的樣本替換最舊的樣本。
一些 DSP 通過(guò)專(zhuān)用訪(fǎng)問(wèn)指令和專(zhuān)用寄存器來(lái)實(shí)現循環(huán)緩沖區的起始地址和結束地址。指針每次遞增時(shí),硬件都會(huì )將其與結束地址進(jìn)行比較,并相應地回繞。這意味著(zhù)同時(shí)支持的循環(huán)緩沖區數量受到可用硬件的限制。這也意味著(zhù)每次中斷都需要保留大量額外狀態(tài),而這會(huì )影響延遲。為此,所需的硬件支持不容忽視;在典型的實(shí)施中,需要更復雜的地址生成單元。為了避免這種情況,一些 DSP 要求循環(huán)緩沖區的大小等于 2 的冪次方,緩沖區的地址調整為該大小的倍數??梢酝ㄟ^(guò)將指針與位掩碼進(jìn)行 AND 運算實(shí)現,從而簡(jiǎn)化硬件要求。但是,這樣會(huì )限制這些緩沖區的放置和使用,特別是幾乎無(wú)法直接從高級語(yǔ)言使用緩沖區。由于 M 系列的宗旨是讓一切都能通過(guò) C 語(yǔ)言輕松使用,因此我們需要想出一種更好的方法。
我們的解決方案是將循環(huán)緩沖區分成兩個(gè)不同的操作,其方式與上文討論的反位尋址類(lèi)似。我們將用于生成回繞偏移的指令與離散?聚合指令相結合來(lái)訪(fǎng)問(wèn)這些偏移地址的數據。這就為緩沖區大小和位置提供了靈活性,而且關(guān)鍵路徑上也不需要有專(zhuān)用硬件。 循環(huán)緩沖區生成指令 (VIWDUP) 可創(chuàng )建一個(gè)矢量,其中包含一連串遞增的偏移量,當到達終點(diǎn)位置時(shí)會(huì )回繞到開(kāi)頭(見(jiàn)圖五)。該指令用從 R0 值開(kāi)始的序列填充矢量寄存器 Q0,并在達到 R1 值時(shí)回繞。然后,它將更新后的起始偏移量 2 寫(xiě)回 R0。這條指令的一個(gè)巧妙設計是,每次寫(xiě)入 Q0 的偏移量矢量都是由標量值重新生成的。通常下一條指令就是使用偏移量的離散?聚合指令,因此 Q0 可以直接重復用于其他目的。立即值指定偏移量的增量,這對于處理不同的元素大小非常有用。例如,如果加載的是 32 位數值,將使用四個(gè)字節的增量??梢灾付ㄈ我庠隽炕驕p量,因此該指令可用于其他需要通用數字模式的情況。通過(guò)這種方式,Helium 可以提供任意數量的循環(huán)緩沖區,在內存中具有靈活的大小、方向和對齊方式,而且這個(gè)過(guò)程只需要使用現有的硬件就可以提供序列生成指令。
圖五:序列生成指令的操作示例
那么性能表現如何呢?雖然需要額外的偏移生成指令 (VIWDUP),但我們發(fā)現在許多情況下,可能會(huì )因為與內存訪(fǎng)問(wèn)本身重疊而隱藏了開(kāi)銷(xiāo)。在所有情況下,這一開(kāi)銷(xiāo)都小于在沒(méi)有硬件支持的情況下管理回繞的計算工作量。我們之前也說(shuō)過(guò),出于性能考慮,最好使用連續訪(fǎng)問(wèn)。循環(huán)緩沖區的特別之處在于,大部分訪(fǎng)問(wèn)都是連續的,只有偶爾發(fā)生回繞時(shí)才會(huì )出現不連續。一種方法是離散-聚合指令比較偏移值,然后合并連續的訪(fǎng)問(wèn)。遺憾的是,這樣做將需要大量額外的硬件,并給設計的關(guān)鍵部分增加許多額外的復雜性。在負載連續的情況下,離散?聚合操作會(huì )降低性能,這違背了我們追求將每個(gè) gate 的性能發(fā)揮到極致的原則。
當我們試圖找到解決這個(gè)問(wèn)題的方法時(shí),我們注意到偏移生成指令 (VIWDUP) 已經(jīng)掌握回繞點(diǎn)的位置。如果能將這一信息傳遞給離散-聚合指令,它就能將訪(fǎng)問(wèn)提升為連續訪(fǎng)問(wèn),而無(wú)需使用昂貴又耗時(shí)的偏移比較器。那么我們能不能指定一個(gè)額外的標量寄存器來(lái)傳輸這些信息呢?遺憾的是,這將增加所需的讀取端口數量,而且標量依賴(lài)關(guān)系從 VIWDUP 改為離散?聚合指令將會(huì )導致指令無(wú)法重疊。Helium 實(shí)現是否可以將這些信息存儲在隱藏的微架構元數據中,并在矢量發(fā)生修改時(shí)清除元數據?一般不建議這樣做,因為元數據需要在中斷時(shí)保留,而這會(huì )影響延遲。但我們發(fā)現,在這種情況下,我們不需要保留元數據。在出現異常的極少數情況時(shí),備選措施是正常執行離散-聚合,而不是優(yōu)化連續訪(fǎng)問(wèn)。通過(guò)使用易失性隱藏元數據來(lái)指示連續訪(fǎng)問(wèn),可以?xún)?yōu)化普通非回繞情況下的性能,同時(shí)避免出現額外的架構狀態(tài)和中斷延遲。
在受限的環(huán)境中工作極具挑戰性,Helium 要求我們不斷尋找創(chuàng )新的解決方案,充分發(fā)揮硬件性能。我們努力聯(lián)合設計架構和微架構,尋找一系列內存訪(fǎng)問(wèn)指令,既能滿(mǎn)足 DSP 應用的需要,又能最大限度地減少實(shí)現這些指令所需的硬件數量。 特別是在循環(huán)緩沖區方面,我們延續了 M 系列的傳統,確保每個(gè) gate 都物盡其用,從而以較低的面積實(shí)現性能表現,同時(shí)為終端用戶(hù)提供良好的體驗感。
我們 將在下一篇 Helium 文章中介紹如何通過(guò)一些有趣的循環(huán)處理指令來(lái)避免阿姆達爾 (Amdahl) 定律帶來(lái)的影響。持續關(guān)注 Helium 技術(shù)講堂,我們下期再見(jiàn)!
評論