从 C 中的两个 ymms 填充一个 zmm
fill a zmm from two ymms in C
我想知道用简单包装 (zmm0 = {ymm1,ymm0}) 从两个 m256is 加载 m512i 的最佳方法是什么。我知道 ymm0 是 zmm0 的低位,但不确定我是否可以使用 intrinsic 在 C 中利用它。在 C 中实现此目的的最佳方法是什么?
奇怪,Intel的intrinsics guide里好像没有256->512版本的_mm256_set_m128i
。也许是因为每个 AVX512 内在函数都必须有一个 _mask_
版本?不对,还有_mm512_set_epi32
,真奇怪。
你可以 _mm512_cast
一个到 __m512i
和 vinserti32x8
另一个。 (或者64x4,如果不屏蔽则选择无关紧要。)
#include <immintrin.h>
__m256i merge256(__m128i lo, __m128i hi){
//return _mm256_set_m128i(hi, lo);
return _mm256_set_m128i(hi, lo);
}
#ifdef __AVX512F__
__m512i merge512(__m256i lo, __m256i hi){
__m512i base = _mm512_castsi256_si512(lo); // upper half is don't-care
return _mm512_inserti32x8(base, hi, 1); // insert hi as new upper half
// return _mm512_set_m256i(b, a); // doesn't exist in GCC, clang, ICC, or MSVC
}
#endif
Demo on Godbolt,还包括 128->256 和 _mm256_set_m128i(hi, lo)
对于这些示例,我将 arg 顺序定义为 lo、hi。您可能更愿意将其定义为 hi、lo 以匹配 _mm_set
(而不是 setr
)内在函数。
我想知道用简单包装 (zmm0 = {ymm1,ymm0}) 从两个 m256is 加载 m512i 的最佳方法是什么。我知道 ymm0 是 zmm0 的低位,但不确定我是否可以使用 intrinsic 在 C 中利用它。在 C 中实现此目的的最佳方法是什么?
奇怪,Intel的intrinsics guide里好像没有256->512版本的_mm256_set_m128i
。也许是因为每个 AVX512 内在函数都必须有一个 _mask_
版本?不对,还有_mm512_set_epi32
,真奇怪。
你可以 _mm512_cast
一个到 __m512i
和 vinserti32x8
另一个。 (或者64x4,如果不屏蔽则选择无关紧要。)
#include <immintrin.h>
__m256i merge256(__m128i lo, __m128i hi){
//return _mm256_set_m128i(hi, lo);
return _mm256_set_m128i(hi, lo);
}
#ifdef __AVX512F__
__m512i merge512(__m256i lo, __m256i hi){
__m512i base = _mm512_castsi256_si512(lo); // upper half is don't-care
return _mm512_inserti32x8(base, hi, 1); // insert hi as new upper half
// return _mm512_set_m256i(b, a); // doesn't exist in GCC, clang, ICC, or MSVC
}
#endif
Demo on Godbolt,还包括 128->256 和 _mm256_set_m128i(hi, lo)
对于这些示例,我将 arg 顺序定义为 lo、hi。您可能更愿意将其定义为 hi、lo 以匹配 _mm_set
(而不是 setr
)内在函数。