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

AArch64架构下数组初始化与Neon SIMD操作的性能对比问询

AArch64 Neon Intrinsics 数组构造性能优化问题

在AArch64架构中使用Neon Intrinsics,通过函数参数传入数组并构造修改后的数据,代码如下:

void scenario1(uint16x8_t* X) {

    uint16x8_t arrayTest01[4] = {
          {X[0][4],X[0][5],X[0][6],X[0][7], -X[0][0],-X[0][1],-X[0][2],-X[0][3]},
          {X[1][4],X[1][5],X[1][6],X[1][7], -X[1][0],-X[1][1],-X[1][2],-X[1][3]},
          {X[2][4],X[2][5],X[2][6],X[2][7], -X[2][0],-X[2][1],-X[2][2],-X[2][3]},
          {X[3][4],X[3][5],X[3][6],X[3][7], -X[3][0],-X[3][1],-X[3][2],-X[3][3]}  
    };

    uint16x8_t arrayTest02[4];

    arrayTest02[0] = vextq_u16(X[0], vmulq_n_u16(X[0],-1),4);
    arrayTest02[1] = vextq_u16(X[1], vmulq_n_u16(X[1],-1), 4);
    arrayTest02[2] = vextq_u16(X[2], vmulq_n_u16(X[2],-1), 4);
    arrayTest02[3] = vextq_u16(X[3], vmulq_n_u16(X[3],-1), 4);

    // Rest of code which uses arrayTest01 and/or arrayTest02
}

arrayTest01和arrayTest02均为从scenario1函数外的结构数组生成的查找表,其中的向量均为半正半负(模65536)。

相关背景:

  • 使用arrayTest01时,汇编代码会执行一些AND和取反操作,但不确定-O3编译后是否仍如此,也不清楚初始化时是否会逐个从内存加载元素;
  • vmulq_n_u16操作实现乘以-1(得到-X[i]),vextq_u16操作提取X[i]的上半部分和-X[i]的下半部分;
  • vmulq_n_u16和vextq_u16作为SIMD操作理论上各占1个周期,但不确定最终是否比初始化更快。

由于arrayTest01和arrayTest02将包含数千个条目,且scenario1会被多次调用,因此亟需优化执行时间/周期数。

问题

  1. 初始化数组arrayTest01的元素是否会逐个从内存加载?
  2. 若为是,SIMD操作是否更快?
  3. 总体而言,哪种方式执行速度更快?初始化数组还是用SIMD构造数组?(最终数组将包含数千个条目)

回答

问题1:初始化arrayTest01是否会逐个加载内存元素?

在-O3优化级别下,不会逐个加载内存元素。X传入的是uint16x8_t类型指针,每个X[i]本身是128位Neon向量,编译器会直接把整个向量加载到寄存器,再通过**向量lane提取(如vgetq_lane_u16)和向量组合(如vcombineq_u16)**生成arrayTest01的元素。但这个过程需要拆分原向量的每个lane,再重新组合成新向量,会产生多条lane级操作指令,而非单条SIMD指令完成整个向量构造。

问题2:SIMD操作是否更快?

是的。arrayTest02使用的vmulq_n_u16和vextq_u16都是单周期SIMD指令:

  • vmulq_n_u16(X[i], -1)本质是对整个向量的8个16位元素同时执行取反操作,单指令完成8个元素的计算;
  • vextq_u16直接从两个输入向量中提取指定偏移的连续8个元素,一步完成新向量的拼接。
    相比arrayTest01需要对每个lane单独提取、取反再组合的多指令序列,SIMD指令的吞吐量和延迟优势明显。

问题3:数千条目下哪种方式更快?

毫无疑问是**SIMD构造(arrayTest02的方式)**更快,核心原因有两点:

  1. 指令吞吐量差距:arrayTest01每个向量需要至少8条lane提取+8条取反+1条向量组合指令,而arrayTest02每个向量仅需2条SIMD指令,指令数量的差距会随条目数增加线性放大;
  2. 并行执行效率:SIMD指令专为批量数据设计,AArch64的Neon单元支持多指令并行调度,vmulq_n_u16和vextq_u16可以在流水线中连续执行,而lane级操作更容易产生数据依赖,限制并行度。

额外优化建议:如果scenario1被多次调用且X内容固定,可以把构造好的查找表移到函数外预计算,避免每次调用重复构造,能进一步降低运行时间。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 08:05:27