簡體   English   中英

go 從 avx/sse 掩碼到 avx512 掩碼的“正確”方法是什么?

[英]What is the “correct” way to go from avx/sse masks to avx512 masks?

我有一些現有的 avx/sse 掩碼,這些掩碼采用舊方法:

auto mask_sse = _mm_cmplt_ps(a, b);
auto mask_avx = _mm_cmp_ps(a, b, 17);

在某些情況下,將舊 avx 代碼與新 avx512 代碼混合時,我想將這些舊樣式掩碼轉換為新的 avx512 __mmask4__mmask8類型。

我試過這個:

auto mask_avx512 = _mm_cmp_ps_mask(sse_mask, _mm_setzero_ps(), 25/*nge unordered quiet*/);

它似乎適用於比較的普通舊輸出,但我認為它不會正確捕獲可以與 sse4.1 _mm_blendv_ps一起使用的正 NAN。

還有一個很好的舊_mm_movemask_ps但看起來它將掩碼一直放在通用寄存器中,我需要用_cvtu32_mask8將它鏈接到一個專用掩碼寄存器中。

有沒有一種更簡潔的方法可以直接將符號位從舊式掩碼中拉出到 k 寄存器之一中?

示例代碼:

這是一個示例程序,按照我上面提到的第一種方式進行掩碼轉換

#include "x86intrin.h"
#include <cassert>
#include <cstdio>

int main()
{
    auto a = _mm_set_ps(-1, 0, 1, 2);
    auto c = _mm_set_ps(3, 4, 5, 6);

    auto sse_mask    = _mm_cmplt_ps(a, _mm_setzero_ps());
    auto avx512_mask = _mm_cmp_ps_mask(sse_mask, _mm_setzero_ps(), 25);

    alignas(16) float v1[4];
    alignas(16) float v2[4];
    _mm_store_ps(v1, _mm_blendv_ps(a, c, sse_mask));
    _mm_store_ps(v2, _mm_mask_blend_ps(avx512_mask, a, c));

    assert(v1[0] == v2[0]);
    assert(v1[1] == v2[1]);
    assert(v1[2] == v2[2]);
    assert(v1[3] == v2[3]);
    return 0;
}

首先使用 AVX-512 比較內在函數來獲得 AVX-512 掩碼(如_mm_cmp_ps_mask ); 這將比比較成向量然后轉換它要有效得多,除非編譯器為您優化了這種低效率。 (考慮使用像Agner Fog 的 VCL這樣的包裝庫來嘗試抽象出差異。VCL 許可證最近從 GPL 更改為 Apache。)


但是如果你真的需要這個(例如作為你完成優化之前的權宜之計),你就不需要 FP compare _mm_cmp_ps中的 _mm_cmp_ps 產生__m128結果,但它並不是真正的浮點向量1 它是全一位/全零位。 您只需要這些位,因此您正在尋找與vmovmskps等效的 AVX-512,但在k寄存器中而不是 GP integer 中。 VPMOVD2M k, x/y/zmm用於 32 位源元素。

   __m128 cmpvec = _mm_cmplt_ps(v, _mm_setzero_ps() );
   __mmask8 cmpmask = _mm_movepi32_mask( _mm_castps_si128(cmpvec) );   // <----

// equivalent to comparing into a mask in the first place:
   __mmask8 cmpmask = _mm_cmplt_ps_mask(v, _mm_setzero_ps(), _CMP_LT_OQ);

// equivalent to (if I got this right)
   __mmask8 cmpmask = _mm_fpclass_ps_mask(v, 0x40 | 0x10);  // negative | negative_inf

https://uops.info/現在已關閉,否則我會將 VPMOVD2M 與 VCMPPS 的延遲和執行端口檢查為掩碼(對於 UNORD 謂詞)與 VFPCLASSPS。


腳注 1:您可以將 AVX-512 vfpclassps用於掩碼,甚至可以使用諸如 UNORD 之類的vcmpps謂詞與自身進行比較,以檢測 NAN 與否。 但我認為這些比較慢。


我需要用_cvtu32_mask8將其鏈接到一個專用掩碼寄存器中。

編譯器目前做事的方式, __mmask8只是unsigned char的 typedef,而__mmask16unsigned short 它們可以在沒有內在函數的情況下自由轉換,無論好壞。 但是在 asm 中,需要一個kmovb k1, eax指令才能將數據從 GP reg 獲取到 ak mask reg,並且該指令只能在當前 CPU 的端口 5 上運行。

暫無
暫無

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

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