新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Armv9 技術講堂 | SME 指令介紹

        Armv9 技術講堂 | SME 指令介紹

        作者: 時間:2024-08-13 來源:Arm 收藏

        可伸縮矩陣擴展 () 作為 v9 架構中的一項創新特性,旨在滿足當前日益復雜和高能耗的人工智能 (AI) 和機器視覺 (ML) 應用需求。除了加速現今的 AI, 也提供了在 架構上處理不斷更新的生成式 AI 應用的靈活性。在 上一篇內容 中,Arm 技術專家為大家簡要介紹了 ,本周我們將帶各位更為詳細地來了解 SME 的指令,助力你在應用中高效使用 SME!

        本文引用地址:http://www.104case.com/article/202408/461972.htm

        操作 ZA 存儲的 SME 指令主要包括:計算兩個向量外積,并累加或累減,將結果放入一個 ZA tile 的指令;內存與 ZA tile 行或列之間的存取操作指令,以及 SVE Z 寄存器和 ZA tile 行或列之間的移動指令;水平或垂直方向上,一個 Z 向量與 ZA tile 的加法指令;將一個標量寄存器加上 Streaming SVE 模式的向量長度倍數的指令。

         

        外積并累加或累減指令

         

        為了幫助理解外積并累加或累減指令,讓我們看看如何使用外積操作來做矩陣乘法。下圖展示了外積運算:

        計算 a 和 b 兩個向量的外積,可以得到他們外積的結果,即矩陣 C。

        現在我們看看如果進行矩陣 a 和 b 的矩陣乘:

        這個矩陣乘可以通過計算兩次外積操作再累加兩個外積結果來實現,如下圖所示:

        SME 為 8 位、16 位整數,以及 FP16、BF16、FP32 和 FP64 浮點數引入了高效的外積并累加或累減指令。這些指令計算放在兩個 Z 向量寄存器(Zn 和 Zm)里的向量的外積,并將這個外積結果累加或累減一個 ZA tile (ZAda) 中已有數據,將結果存入同一 ZA tile (ZAda)。每個源向量都可以被其相應的控制 predicate 寄存器(Pn 和 Pm)獨立地 predicate。

         

        FP32、FP64 外積并累加或累減指令

        那些輸入向量和輸出數組有同樣數據類型(FP32 和 FP64)的指令相對直觀。下面這一例子展示了 FP32 類型的外積并累加或累減指令。

        這個例子中,假設 SVL 向量長度為 128 位,Zn.S 和 Zm.S 中存放了四個 FP32 數組成的向量,此指令計算 Zn.S 和 Zm.S 的外積,外積結果為圖中灰色的矩陣,然后將此外積結果累加或累減 ZAda.S 這個 ZA tile(矩陣)中原有的值,將結果存入同一 ZAda.S tile 中。

         

        FP16、BF16、INT16、INT8、 I16I64 類型

        的 外積并累加或累減指令

        為了保持這些數據類型結果的精度,以及充分利用計算硬件資源和 ZA 存儲,這些指令會擴大計算結果數據類型,因此這些操作不像前面 FP32 和 FP64 類型指令那么直接。

        BF16 指令計算兩個 BF16 的外積的和,擴大結果類型為 FP32,然后這些結構被解構性地從目標 tile 中加或減。

        INT8 指令計算四個 INT8 的外積的和,擴大結果類型為 INT32,然后這些結構被解構性地從目標 tile 中加或減。

        INT16 指令計算兩個 INT16 的外積的和,擴大結果類型為 INT32,然后這些結構被解構性地從目標 tile 中加或減。

        FP16 指令計算兩個 FP16 的外積的和,擴大結果類型為 INT32,然后這些結構被解構性地從目標tile中加或減。

        如果實現了 FEAT_SME_I16I64,I16I64 指令計算四個 INT16 的外積的和,擴大結果類型為 INT64,然后這些結構被解構性地從目標 tile 中加或減。

        以下例子展示了 SVL 向量長度為 128 位的 INT8 UMOPA 指令進行的操作:

        對于 UMPOA 指令,每個輸入向量 (Zn.B, Zm.B) 被當成一個有 4x4 元素的矩陣,可以看作是四個連續的元素組成的塊(如圖中紅線標出)被轉置了。

        在這個例子中,因為 SVL 向量長度為 128 位,第一源向量 Zn.B 包含一個無符號 8 位整數的 4x4 子矩陣,第二源向量 Zm.B 包含一個無符號 8 位整數的 4x4 子矩陣,UMOPA 指令計算出 4x4 擴大了的 32 位整數外積的和,然后解構性地加上目標 tile (ZAda) 中的整數。

        更通用地說,這條無符號整型外積和并累加指令 (UMOPA) 將第一源向量中的子矩陣乘以第二源向量中的子矩陣。每個源向量包含一個 (SVL/32) x 4 的無符號 8 位整數的子矩陣。然后將得到的 (SVL/32) x (SVL/32) 擴大了的 32 位整數外積和解構性地加上一個 32 位整數目標 tile。

        下面的例子展示了 SVL 為 128 位的 BF16 BFMOPA 進行的操作:

        這個例子中,因為 SVL 為 128 位,第一源向量 Zn.H 包含一個 BF16 浮點數的 4x2 子矩陣,它被擴大為單精度浮點數;第二源向量 Zm.H 包含一個 BF16 浮點數的 2x4 子矩陣,它被擴大為單精度浮點數;BFMOPA 指令計算出 4x4 單精度外積的和,然后解構性地加上目標tile (ZAda) 中的單精度數。

        更通用地說,這條指令 (BFMOPA) 擴大了存放在第一源里的 (SVL/32) x2 BF16 子矩陣的類型為單精度,擴大了存放在第二源里的 2x (SVL/32) BF16 子矩陣的類型為單精度,將這兩個子矩陣相乘。然后將得到的 (SVL/32) x (SVL/32) 單精度外積和解構性地加上一個單精度目標 tile。

        下表顯示了幾種數據類型和 SVL長度的一條外積并累加或累減指令所做的對應數據類型的 MAC(乘累加)數量:

         

        帶 Predication 的 SME 指令

         

        每個源向量都可以被其相應的控制 predicate 寄存器獨立地 predicate:

        外積并累加或累減指令使用 Pn/M 和 Pn/M(沒有 /Z 形式):inactive 的源元素被當成具有 0 值。

        Slice 移動 (move) 指令使用 Pg/M:目標 slice 中 inactive 的元素保持不變。

        Tile slice 加載 (load) 指令使用 Pg/Z:目標 tile slice 中的 inactive 元素被設置為 0。

        Tile slice 存儲 (store) 指令使用 Pg:inactive 的元素不會寫入內存。

        Predication 讓矩陣的維數不是 SVL 的倍數的情況更容易處理。如下面這一例子所示:

        輸入向量 Z0 被 P0 predicate,Z1 被 P1 predicate。在這個例子里,SVL 為 512 位,Z 寄存器包含 16 個 FP32 數組成的向量,P0 中最后兩個元素是 inactive 的,而 P1 中最后一個元素是 inactive 的。這條指令更新 ZA0.S 中 (16-2) x (16-1) 個 FP32 元素,因為使用了 Pn/M,ZA0.S 中剩下的元素保持不變。

        下圖展示了更多的 predicated 外積并累加或累減的例子。圖中被劃線的文字表示被 inactive predicate 元素影響的計算部分。

         

        ZA tile 與一個 Z 向量的加運算

         

        SME 包括 ZA tile 的行或列都加上一個向量的指令

        例如:

        它進行以下操作:

        這個 ADDHA 指令將源向量 Z1 中的每個元素加上 ZA0.S tile 每一水平 slice 的相應 active 元素。Tile 中元素被一對控制 predicate 進行 predicate。一個水平 slice 中的一個元素在下面情況下可以認為是 active:它在第二控制 predicate 對應的元素是 true,并且它在第一 控制 predicate 對應的水平 slice 行號也為 true,目標 tile 中 inactive 元素保持不變。

         

        Tile 存取和移動指令

         

        SME tile 存取和移動 (load, store, move) 指令可以:

        從內存讀取數據,放入 ZA tile 的行或列

        將 ZA tile 的行或列寫入內存

        將 ZA tile 的行移動到 SVE Z 向量寄存器

        將 SVE Z 向量寄存器移動到 ZA tile 行或列

         

        Tile slice 存取指令

         

        LD1B、LD1H、LD1S、LD1D 和 LD1Q 指令從內存中連續讀取一些值到 ZA tile slice,數據類型分別是 8 位、16 位、32 位、64 位和 128 位元素。ST1B、ST1H、ST1S、ST1D 和 ST1Q 指令將 ZA tile slice 存入連續內存中,數據類型分別是 8 位、16 位、32 位、64 位和 128 位元素。這些指令也用 predication 的支持,例如:

        此 LD1B 指令執行 predicated 的連續字節讀取,它從地址為 (X1+X2) 的內存讀取數據到 ZA0 中行號為 (W0+imm) 的這個水平 tile slice 中。目標 tile slice 中 inactive 的元素被設置為 0。

        此 ST1H 指令執行 predicated 連續半字的存操作,它將 ZA1 中列號為 (W0+imm) 的垂直 tile slice 存到地址為 (X1+X2*2) 的內存,tile slice 中 inactive 的元素不寫入內存。

         

        Tile slice 移動指令

         

        MOV 指令(MOVA 指令的別名)將一個 Z 向量寄存器的值移動到一個 ZA tile slice,或將一個 ZA tile slice 中的值移動到一個 Z 向量寄存器。這條指令操作帶指定元素大小的 ZA tile 的單個水平或垂直 tile slice。Slice 的行號/列號由 slice 的檢索寄存器加上立即數偏移指定。目標 slice 中 inactive 的元素保持不變。

        例如:

        此指令將向量寄存器 Z0.B 中的值移動到 ZA0H.B[W0, #imm] 這個水平 ZA tile slice 中,使用 P0 作為 predication 寄存器。目標 tile slice 中 inactive 的元素保持不變。

         

        ZA array 向量存取指令

         

        SME LDR 指令從內存讀取數據到一個 ZA array 向量,SME STR 指令將一個 ZA array 向量中的值存入內存。這些指令是不帶 predication 功能的。它們主要是為了軟件上下文切換時,對 ZA  存儲進行保存或恢復。SME LDR/STR 指令也可以在 Non-streaming SVE 模式下,當 PSTATE.ZA 使能的情況下使用。例如,下面的 STR 指令的 ZA array 向量是由一個向量選擇寄存器 Wv(標量寄存器 W)加上可選的立即數 (Wv+Imm) 指定。訪問內存的地址為:一個標量寄存器作為基礎,加上相同的可選立即數偏移乘以當前向量長度字節數。

         

        ZA tile 清零指令

         

        SME 清零 (ZERO) 指令可以清零一組 64 位 ZA tile:

        清零指令可以清零多到八個名為 ZA0.D 到 ZA8.D 的 ZA tile,哪些 tile 要清零由指令中的 mask 指定,剩下的其他 tile 保持不變。這條指令也可以在 Non-streaming SVE 模式,當 PSTATE.ZA 使能的情況下使用。如果要清零整個 ZA array,可以使用一個指令別名,即 ZERO {ZA}。

         

        新的 SVE2 指令

         

        SME 構架擴展加入了一些新的 SVE2 指令,這些指令也可以在 PE 實現了 SVE2,且處于 Non-streaming SVE 模式時使用。這些指令包括:

        選擇一個 predicate 寄存器或是 all-false 的 predicate 選擇指令

        翻轉 (reverse) 64 位雙字元素的指令

        有符號/無符號鉗位為更小/更大值向量的指令

         

        PSEL 指令

        PSEL 指令選擇一個 predicate 寄存器或是 all-false 到目標 predicate 寄存器,如下所示:

        如果指令中第二源 predicate 寄存器 (Pm) 中指定的元素為 true,這條指令將第一源 predicate 寄存器 (Pn) 的內容放到目標 predicate 寄存器 (Pd),否則設置目標 predicate 寄存器的值全部為 false。例如以下指令,假設 W12 的值為 0:

        第二源 predicate 寄存器的 [W12+0] 即 [0] 個元素為 false,因此目標寄存器 P0 被設置為全 0 (all-false),如下圖所示:

        現在來看如下指令,仍然假設 W12 的值為 0,但這次立即數偏移為 1:

        第二源 predicate 寄存器的 [W12+1] 即 [1] 個元素為 true,因此選擇第一源 predicate 寄存器的值到目標寄存器 P0,如下圖所示:




        關鍵詞: Arm SME

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 楚雄市| 墨玉县| 大名县| 连州市| 临沧市| 永修县| 昌吉市| 荣昌县| 怀来县| 淮阳县| 仁怀市| 苏尼特左旗| 林周县| 铁岭县| 九江市| 高台县| 乌恰县| 东乡族自治县| 麻城市| 尼玛县| 高雄市| 天柱县| 化州市| 新邵县| 汾阳市| 海晏县| 义马市| 沽源县| 连南| 靖西县| 娄烦县| 井研县| 龙游县| 南部县| 天水市| 扎赉特旗| 孟州市| 新竹市| 视频| 铁岭市| 乌拉特前旗|