簡體   English   中英

英特爾內部文檔中的“MAX”指的是什么?

[英]What is "MAX" referring to in the intel intrinsics documentation?

intel 內在函數指南中,一些操作是使用術語“MAX”定義的。 一個例子是__m256 _mm256_mask_permutexvar_ps (__m256 src, __mmask8 k, __m256i idx, __m256 a) ,它被定義為

FOR j := 0 to 7
    i := j*32
    id := idx[i+2:i]*32
    IF k[j]
        dst[i+31:i] := a[id+31:id]
    ELSE
        dst[i+31:i] := 0
    FI
ENDFOR
dst[MAX:256] := 0

. 請注意此定義中的最后一行: dst[MAX:256]:= 0 MAX指的是什么,這條線是否添加了任何有價值的信息? 如果我不得不做出假設,那么MAX可能意味着向量中的位數,在_mm256的情況下為256 然而,這似乎並沒有改變操作的定義,也可能被省略。 但是為什么會在那里呢?

此偽代碼僅對從中復制它的程序集文檔有意義,而不適用於 intrinsics (英特爾的第 2 卷 PDF 記錄了相應的vpermps asm 指令的HTML 刮擦。)

   ...
ENDFOR
DEST[MAXVL-1:VL] ← 0

(相同的 asm 文檔條目涵蓋 VL = 128、256 和 512 位版本,即指令的向量寬度。)

在 asm 中,YMM 寄存器是 ZMM 寄存器的低半部分,寫入 YMM 會將高位歸零到 CPU 支持的最大向量寬度(就像將 EAX 零擴展寫入 RAX 一樣)。

您選擇的內在函數用於掩碼版本,因此它需要AVX-512(EVEX 編碼),因此 VLMAX 至少為 512 1 如果掩碼是一個常量全1,它可以優化為 AVX2 VEX 編碼,但仍然是 VLMAX 的完整寄存器的零高位。

這對內在函數沒有意義

內在函數 API 只有__m256__m512類型; __m256並不隱含地是__m512的下半部分。 您可以使用_mm512_castps256_ps512來獲得一個__m512與您的__m256作為低半部分,但API 文檔說結果的高 256 位未定義”。 因此,如果您在 function arg 上使用它,它不會強制它對vmovaps ymm7, ymm0或其他東西進行零擴展,以防調用者留下高垃圾。

如果您在來自此 function 的內在函數的_mm512_castps256_ps512 __m256無論它是留在 reg 中還是被存儲/重新加載,它幾乎總是會以零的高半部分進行編譯,但是 ZDB974238714CA8DE6FZA7ACE不能保證這一點。 (如果編譯器選擇將先前的計算與其他計算相結合,使用 512 位操作,您可能會得到一個非零的高半部分。)如果您想要高零,則沒有等效於_mm256_set_m128 (__m128 hi, __m128 lo) ,所以你需要一些其他明確的方式。


腳注 1 :或者通過一些假設的未來擴展, VLMAX aka MAXVL可能會更寬。 它由 XCR0 的當前值決定。 本文檔告訴您,這些說明仍將歸零。

(我還沒有研究在支持 AVX-512 的機器上是否可以更改 VLMAX,或者它是否是只讀的。IDK 如果你可以更改它,CPU 將如何處理它,比如可能根本不運行 512 位指令. 主流操作系統當然不會這樣做,即使特權操作是可能的。)

SSE 沒有任何已定義的擴展向量的機制,並且一些現有代碼(特別是 Windows kernel 驅動程序)手動保存/恢復了一些 XMM 寄存器供自己使用。 為了支持這一點,AVX 決定舊版 SSE 將保留 YMM/ZMM 寄存器的高位部分不變。 但是為了有效地使用非 VEX 傳統 SSE 編碼運行現有機器代碼,它需要昂貴的 state 轉換(Haswell 和 Ice Lake)和/或錯誤依賴項(Skylake): 為什么在 Skylake 上沒有 VZEROUPPER 時,這個 SSE 代碼會慢 6 倍?

英特爾不會再犯這個錯誤,因此他們將 AVX 定義為將 CPU 支持的任何向量寬度歸零,並在每個 AVX 和 AVX-512 指令編碼中清楚地記錄它。 因此 VEX 和 EVEX 可以自由混合,甚至有助於節省機器代碼大小:

dst[MAX:256]:= 0將所有高於(包括)第 256 位的位設置為零。 它僅與超過 256 位的寄存器有關。 因此,如果寄存器長度為 256 位,則 MAX 可以為 256;如果處理器使用 512 位寄存器,則 MAX 可以為 512。

寄存器中的位在“左側”以高索引編號,在“右側”以低索引編號。 這與我們寫和談論二進制數字的方式相吻合:10010 2是 18 的二進制數字,左邊是位號 4,代表 2 4 = 16,右邊是位號 0,代表 2 0 = 1。

R[ m : n ] 表示寄存器 R 從mn的位集合,其中m是集合的“左”端, n是“右”端。 如果m小於n ,則它是空集。 因此,對於 512 位的寄存器, dst[511:256]:= 0表示將 511 到 256 位設置為零,而對於 256 位的寄存器, dst[255:256]:= 0表示什么都不做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM