在支持AVX-512和BF 16的中央处理器上,您可以使用512位载体寄存器来存储32个16位浮点数.
我找到了可以将FP 32值转换为BF 16值的内部函数(例如:_mm512_cvtne2ps_pbh),但我还没有找到任何可以直接从内存加载BF 16值的内部函数.如果我总是将这些值转换为BF 16,那么总是在FP 32中加载这些值似乎有点浪费.是否不支持直接BF 16加载,或者我只是还没有找到合适的内在内容?
在支持AVX-512和BF 16的中央处理器上,您可以使用512位载体寄存器来存储32个16位浮点数.
我找到了可以将FP 32值转换为BF 16值的内部函数(例如:_mm512_cvtne2ps_pbh),但我还没有找到任何可以直接从内存加载BF 16值的内部函数.如果我总是将这些值转换为BF 16,那么总是在FP 32中加载这些值似乎有点浪费.是否不支持直接BF 16加载,或者我只是还没有找到合适的内在内容?
内在学中奇怪的疏忽. asm中没有针对BH 16的特殊vmov
指令,因为您不需要:您只需使用vmovups
,因为asm不关心类型. (除了有时是integer与FP域之外,所以可能更喜欢FP加载或存储指令- integer vmovdqu16
可能在某些处理器上有一个额外的从加载到FP LU转发的延迟周期.)
如果对齐的加载/存储适用于您的用例,只需将__m512bh*
指向您的数据并go 引用它即可.(100 -它被明确定义为等效于对齐的加载或存储固有内容,并且允许别名任何其他数据).
如果不是,那么正如@chtz指出的那样,您可以将memcpy
转换到/从__m512bh
变量. 现代编译器知道如何内联和优化小的固定大小memcpy,尤其是变量的确切大小. @chtz's demo on Godbolt表明它优化了我们想要的方式,即用海湾合作委员会和clang -O1
,就像使用__m512bh*
的deref一样,但适用于未对齐.
但对于MSVC来说就不太好了;它工作正常,但本地var的memcpy实际上保留了堆栈空间并将值存储到它,并将其留在ZMM 0中作为返回值. (不重新加载副本,但不将存储和死存储优化为res
.)
对于内在演员,甚至没有来自__m512
、__m512d
或__m512i
的内在演员阵容. (或者对于任何较窄的载体宽度.)
但大多数编译器也允许您对vector类型使用C风格的强制转换,就像这样将比特重新解释(类型双关语)为不同的vector类型:
__m512bh vec = (__m512bh) _mm512_loadu_ps( ptr ); // Not supported by MSVC
这是not,是由Intel's intrinsics guide定义的标准事物,但GCC和clang至少以与intrinsics API的函数(例如_mm512_castsi512_ps
或_mm512_castps_ph
)相同的方式实现C风格的强制转换(以及C++ std::bit_cast
,可能是static_cast
)(我们希望BF 16存在的FP 16固有功能).
AVX-512负载内部函数需要void*
,这表明可以在任何类型的数据上使用它们. 因此,这只需不转换指针,只需转换载体数据即可.
256位和128位的整值加载/存储分别采用__m256i*
或__m128i*
个指针,FP加载采用float*
个指针. 但执行_mm_loadu_ps( (float*)&int_vector[i] )
仍然是严格别名安全的. 无论如何,一旦你得到__m256
或__m128
,(__m256bh) vec
就可以在大多数编译器中工作.
MSVC对这个演员阵容感到窒息. 如果您使用C++,您可能会使用C++20 std::bit_cast<__m512h>( vec )
for MSVC. But if you want to write portable C that compiles efficiently on MSVC as well as GCC/Clang, your only option might be to deref an aligned pointer. memcpy
在MSVC上编译到死存储,转换值不起作用,并且向量指针的derref需要在GCC/Clang上对齐. MSVC始终避免对指令版本进行配置判断,因此,如果您愿意使用#ifdef
,则可以安全地在MSVC上删除未对齐的__m512h*
.
(在没有AVX的情况下对__m128*
进行反引用是不安全的,因为它可能会折叠到像addps xmm0, [rdi]
这样的内存源操作数中,这确实需要对齐,但这仅适用于遗留SSE的事情. VEX /BEP编码默认允许未对齐. 原始deref不会创造vmovntps
个只提供满足需求口味的store ;如果需要vmovxxx
,即使已知指针已对齐,它也会使用vmovups
而不是vmovaps
. 与MSVC和classic ICC不同,当它们能够证明其安全时,就会使用强制执行指令.)