yue*_*ing 4 simd instruction-set intrinsics avx2 avx512
以下功能似乎在AVX512上不可用:
__m512i _mm512_sign_epi16 (__m512i a, __m512i b)
Run Code Online (Sandbox Code Playgroud)
它会很快面世还是有其他选择?
如果不需要调零部分,则只需要2条指令(和调零的寄存器):
您可以_mm512_movepi16_mask()将符号位放入掩码(的AVX512版本pmovmskb)中,并从零进行合并掩码减法,以基于另一个符号取向量。
#ifdef __AVX512BW__
// does *not* do anything special for signs[i] == 0, just negative / non-negative
__m512i conditional_negate(__m512i target, __m512i signs) {
__mmask32 negmask = _mm512_movepi16_mask(signs);
// vpsubw target{k1}, 0, target
__m512i neg = _mm512_mask_sub_epi16(target, negmask, _mm512_setzero_si512(), target);
return neg;
}
#endif
Run Code Online (Sandbox Code Playgroud)
矢量- >掩模具有对SKYLAKE微架构-X 3周期的延迟(与vpmovw2m,vptestmw或vpcmpw),但使用掩模只具有另一个1个周期的延迟。因此,从输入到输出的延迟为:
signs-> SKX上的结果开始4个周期target-> SKX上的结果开始1个周期(只是vpsubw从零开始屏蔽)。同样要应用is-zero条件:您可以对向量执行的下一个操作零屏蔽或合并屏蔽,因此未使用的元素应该为零。
您需要比较创建另一个面具一个额外的,但你可能并不需要浪费第2个额外的指令,立刻应用。
如果您真的想构建一个自包含的vpsignw方法,我们可以做最后的零掩码,但这是4个内在函数,可编译为4条指令,并且吞吐量可能比@wim的min / max / multiply差。但这具有良好的关键路径延迟,在SKX上总共大约有5个周期(如果可以将最终的遮罩折叠成其他东西,则为4个周期)。关键路径是迹象->遮罩,然后是遮罩子。signs-> nonzeromask可以与任何一个并行运行。
__m512i mm512_psignw(__m512i target, __m512i signs) {
__mmask32 negmask = _mm512_movepi16_mask(signs);
// vpsubw target{negmask}, 0, target merge masking to only modify elements that need negating
__m512i neg = _mm512_mask_sub_epi16(target, negmask, _mm512_setzero_si512(), target);
__mmask32 nonzeromask = _mm512_test_epi16_mask(signs,signs); // per-element non-zero?
return _mm512_maskz_mov_epi16(nonzeromask, neg); // zero elements where signs was zero
}
Run Code Online (Sandbox Code Playgroud)
可能地,编译器可以这种零掩蔽折叠vmovdqu16禀成合并掩蔽为add/ or/ xor或零掩码乘/ and。但是,自己动手做可能是个好主意。
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |