AVX2优化:从__m256i提取非零int32元素至__m128i
高效转换AVX2向量提取非零元素到128位向量
针对你描述的__m256i向量结构[0,a,0,b,0,c,0,d],要提取出[a,b,c,d]到__m128i,可以用整数扩展指令替代高成本的vpermd,实现更优的性能:
优化后的代码
__m128i y = _mm256_extracti128_si256(_mm256_cvtepi64_epi32(x), 0);
原理说明
- 将原256位向量视为4个
int64_t元素:[0|a, 0|b, 0|c, 0|d](每个int64的高32位是0,低32位是目标值a/b/c/d) _mm256_cvtepi64_epi32会将每个int64元素符号扩展为int32,由于你的目标值都是正整数,符号扩展后直接保留低32位的有效值,输出的__m256i结构为[a,b,c,d,0,0,0,0]- 最后用
_mm256_extracti128_si256提取低128位,即可得到[a,b,c,d]的128位目标向量
性能对比
- 原方案生成的
vpermd指令在Intel Skylake及后续CPU上延迟为3周期,吞吐量1周期/指令 - 优化方案生成的
vpmovsxdq(延迟1周期,吞吐量1周期/指令)+vextracti128(延迟1周期,吞吐量1周期/指令),整体延迟和吞吐量都更优,在依赖链较长的场景下性能提升尤为明显
内容的提问来源于stack exchange,提问作者Kevin Meier
相关产品推荐
相关产品推荐

