Optimization 创建掩蔽kreg值的有效方法
Intel的AVX-512扩展的一个好处是,除了向量寄存器外,还可以提供一个kreg来指定要应用于操作的掩码,从而几乎可以屏蔽所有操作:掩码排除的元素可以设置为零,也可以保留其以前的值 kreg的一个特别常见的用途是创建一个掩码,该掩码在向量的开始或结束处排除N个连续元素,例如,作为向量化循环中的第一次或最后一次迭代,其中将处理少于完整向量。例如,对于121Optimization 创建掩蔽kreg值的有效方法,optimization,x86,simd,avx512,Optimization,X86,Simd,Avx512,Intel的AVX-512扩展的一个好处是,除了向量寄存器外,还可以提供一个kreg来指定要应用于操作的掩码,从而几乎可以屏蔽所有操作:掩码排除的元素可以设置为零,也可以保留其以前的值 kreg的一个特别常见的用途是创建一个掩码,该掩码在向量的开始或结束处排除N个连续元素,例如,作为向量化循环中的第一次或最后一次迭代,其中将处理少于完整向量。例如,对于121int32\t值上的循环,前112个元素可由7个完整的512位向量处理,但剩下9个元素可由仅对前9个元素进行操作的屏蔽操作处理 因此,问题是
int32\t
值上的循环,前112个元素可由7个完整的512位向量处理,但剩下9个元素可由仅对前9个元素进行操作的屏蔽操作处理
因此,问题是,给定一个(运行时值)整数r
,它是0-16范围内表示剩余元素的某个值,加载16位kreg的最有效方法是什么,以便设置低位r
位,而不设置剩余位KSHIFTLW
似乎不适合此用途,因为它只需要一个立即数。正是您想要的:从指定位位置开始的零高位。到目前为止,每个使用AVX512的CPU都有BMI2
__mmask16 k = _bzhi_u32(-1UL, r);
这需要2条指令,包括单uop:mov立即指令和BZI
。甚至是单周期延迟。(或KNL上的3个循环)
- 对于
,它将给出0的所有位置零r=0
- 对于
,它只保留低位(位0)表示1r=1
- 对于
,它将位#12或更高归零,留下r=12
(设置了12位)0x0FFF
- 对于
BZHI保留所有32位设置(并设置CF)r>=32
kmovw
,这意味着您的主循环必须使用屏蔽指令。这只适用于rI ASSUBE/hope(~0)>>(16-r)
高效编译为32位MOV immediate+SHRX+KMOVW。呃,我猜这里也有一个sub或neg,x86移位只能通过&31
来屏蔽计数,而不是&15
来屏蔽15位移位。英特尔CPU上更好的序列可能是xor(异或)-zero/BTS/DEC/kmovw的可能重复序列。