You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用AVX2高效计算交错无符号双字(奇数索引)的横向最大值?

4×256位AVX2向量块奇数索引双字最大值提取优化

问题描述

我们需要处理4个256位YMM寄存器(记为ymm0~ymm3),每个寄存器的双字布局为:

ymmX: a7 a6 a5 a4 a3 a2 a1 a0(从左到右为最高位到最低位双字,对应索引7到0)

目标是从每个YMM寄存器的奇数索引双字(a1/索引1、a3/索引3、a5/索引5、a7/索引7)中提取最大值,最终输出一个256位寄存器,布局为:

0 max3 0 max2 0 max1 0 max0

其中max0是ymm0的目标最大值,max1对应ymm1,以此类推;奇数索引位置填充0。目标CPU具备2个洗牌端口,现有方案使用8条指令,需优化性能或指令数。

优化方案(高吞吐量,适配双洗牌端口)

以下方案利用AVX2指令集,通过并行洗牌和高效横向比较减少延迟,同时压缩指令数:

; 注:ymmzero为预定义的全0256位寄存器,mask为立即数0x07050301(对应双字索引7,5,3,1)
; 阶段1:并行提取所有输入YMM的目标双字(双洗牌端口可并行执行2组vpermd)
vpermd ymm4, ymm0, mask
vpermd ymm5, ymm1, mask
vpermd ymm6, ymm2, mask
vpermd ymm7, ymm3, mask

; 阶段2:并行计算横向最大值(单次指令完成两组双字的比较)
vpmaxud ymm4, ymm4, ymm4>>64        ; 合并高/低128位对应双字,得到max(a7,a3)、max(a5,a1)
vpmaxud ymm5, ymm5, ymm5>>64
vpmaxud ymm6, ymm6, ymm6>>64
vpmaxud ymm7, ymm7, ymm7>>64

vpmaxud ymm4, ymm4, ymm4>>32        ; 最终得到每个YMM的最大值,存于低双字
vpmaxud ymm5, ymm5, ymm5>>32
vpmaxud ymm6, ymm6, ymm6>>32
vpmaxud ymm7, ymm7, ymm7>>32

; 阶段3:合并结果到目标布局(仅2条指令完成排列)
vpunpckldq ymm0, ymm4, ymmzero     ; ymm0低128位:0, max0, 0, max1
vpunpckldq ymm1, ymm6, ymmzero     ; ymm1低128位:0, max2, 0, max3
vperm2i128 ymm0, ymm0, ymm1, 0x20  ; 合并高/低128位,得到目标布局

优化点说明

  1. 并行洗牌:借助双洗牌端口,4条vpermd可分为两组并行执行,大幅降低洗牌阶段的总延迟。
  2. 高效横向比较:通过移位+比较的组合,仅用2条指令完成单个YMM寄存器4个双字的最大值计算,避免冗余操作。
  3. 紧凑合并:使用vpunpckldq和vperm2i128仅用2条指令完成4个最大值的布局排列,减少合并阶段的指令开销。

有符号整数适配

若处理的是有符号32位整数,只需将上述代码中的vpmaxud替换为vpmaxsd即可,逻辑完全一致。

内容的提问来源于stack exchange,提问作者Akon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:42:31