如何高效对ZMM寄存器内的8个64位指针进行去重?
ZMM寄存器内8个64位指针的高效去重方案
针对你提到的重复值极少的场景,完全可以利用AVX-512指令集在寄存器内完成去重,全程无需读写内存,性能能达到最优:
核心方案:并行比较+掩码过滤
1. 生成重复标记掩码
利用AVX-512的vpcmpeqq指令,对ZMM寄存器中的每个元素,与后续所有元素做相等比较,通过掩码合并得到每个元素是否存在重复的标记:
; 假设ZMM0存储目标8个64位指针 vmovdqa64 zmm1, zmm0 ; 复制原寄存器值 ; 比较第i个元素和第i+1个元素,合并掩码 vpsrlq zmm1, zmm1, 64 vpcmpeqq k1, zmm0, zmm1 ; 比较第i个元素和第i+2个元素,合并掩码 vpsrlq zmm1, zmm0, 128 vpcmpeqq k2, zmm0, zmm1 vpor k1, k1, k2 ; ... 重复此逻辑,直到完成第i个元素和第i+7个元素的比较
最终掩码k1中,置1的位对应位置的元素存在重复。
2. 提取唯一元素
用knotw取反掩码得到唯一元素的标记,再通过vcompressq将唯一元素压缩到寄存器低位:
knotw k2, k1 ; 取反,标记唯一元素 vcompressq zmm2, k2, zmm0 ; 把唯一元素压缩到zmm2的连续低位
之后可以用kortestw或popcnt统计掩码k2的置位数量,确定唯一元素的个数,再逐个处理即可。
针对低重复率的优化
- 因为重复极少,可以先做相邻元素快速检查:如果相邻比较没有命中重复,直接跳过后续全量比较,节省指令周期。
- 若重复值大概率是固定值(比如NULL指针),可以直接用
vpcmpeqq和该固定值生成过滤掩码,指令数更少、性能更高。 - 全程依赖寄存器内操作,完全规避内存延迟影响。
内容的提问来源于stack exchange,提问作者ajp
相关产品推荐
相关产品推荐

