簡體   English   中英

從基本類型(例如short)到與_mm256_broadcast_epi(例如_mm_broadcastw_epi16)一起使用,填充__m128i 參數的正確方法是什么?

[英]What is the correct way to fill a __m128i parameter, from basic type (such as short), to use with _mm256_broadcast_epi (such as _mm_broadcastw_epi16)

_mm256_broadcastb_epi8、_mm_broadcastw_epi16、_mm256_broadcastd_epi32和_mm256_broadcastq_epi64這四個函數都是VPBROADCASTB、VPBROADCASTW、VPBROADCASTD和VPBROADCASTQ指令的內在函數根據英特爾的文檔: “英特爾® 高級矢量擴展編程參考” ,這些指令可能會相應地接收 8 位、16 位、32 位、64 位內存位置。
第 5-230 頁:

源操作數是XMM寄存器中的8位、16位、32位、64位內存位置或低8位、16位、32位、64位數據

但是,這些指令的內在 API(Intel、MSVS 和 gcc)接收一個 __m128i 參數。 現在,如果我有一個基本類型的變量,據說是“short”,那么最有效和跨平台的方式(至少在 MSVS 和 gcc 之間)將該變量傳遞給相應的廣播內在函數(_mm_broadcastw_epi16 在短的情況下)是什么?

例如:

void func1(uint8_t v) {
    __m256i a = _mm256_broadcastb_epi8(<convert_to__m128i>(v));
    ...
}

void func1(uint16t v) {
    __m256i a = _mm256_broadcastw_epi16(<convert_to__m128i>(v));
    ...
}

void func1(uint32_t v) {
    __m256i a = _mm256_broadcastd_epi32(<convert_to__m128i>(v));
    ...
}

void func1(uint64_t v) {
    __m256i a = _mm256_broadcastq_epi64(<convert_to__m128i>(v));
    ...
}

<convert_to__m128i> 應該是什么,以便最高效和跨平台(如果可能)?

例如,對於 MSVS,可以執行以下操作:

void func1(uint16t v) {
    __m128i vt;
    vt.m128_u16[0] = v;
    __m256i a = _mm256_broadcastw_epi16(vt);
    ...
}

但是如果沒有優化,它可以首先加載一個 xmm 寄存器,然后才在 VPBROADCASTW 中使用它。 當進行優化時,它可以直接使用 v 的內存位置。 它也僅對 MSVS 有效。

已經有序列/復合內在函數可以完全滿足您的要求:

_mm256_set1_epi8/16/32/64

來自英特爾的內在指南:

將 8 位整數 a 廣播到 dst 的所有元素。 這個內在函數可以生成 vpbroadcastb。

使用這些,您應該能夠信任編譯器生成最佳代碼。

在做這樣的事情時,我使用 Intel Intrinsics Guide,這很有幫助,因為您可以從助記符反向搜索(在這種情況下,您知道您最終想要 vpbroadcastb),它會告訴您哪些內在函數與之相關。

如果您有一個標量值開始,只需讓編譯器為_mm256_set1_epi8(scalar)內在函數發出廣播指令,而不是__m128i


但是你通常也不想要_mm_broadcastb_epi8 ( __m128i結果) 或__m256i _mm256_broadcastb_epi8(__m128i)除非你已經有一個__m128i開始並想要低元素。

如果您不關心低 dword 的高 2 或 3 個字節,則在沒有編譯器浪費指令的情況下將標量放入__m128i可能是 8 位或 16 位標量的實際問題; 它可能會將movzx加載到一個整數寄存器中,然后使用vmovd或類似的東西。


暫無
暫無

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

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