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会被多次调用,因此亟需优化执行时间/周期数。
问题
- 初始化数组arrayTest01的元素是否会逐个从内存加载?
- 若为是,SIMD操作是否更快?
- 总体而言,哪种方式执行速度更快?初始化数组还是用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的方式)**更快,核心原因有两点:
- 指令吞吐量差距:arrayTest01每个向量需要至少8条lane提取+8条取反+1条向量组合指令,而arrayTest02每个向量仅需2条SIMD指令,指令数量的差距会随条目数增加线性放大;
- 并行执行效率:SIMD指令专为批量数据设计,AArch64的Neon单元支持多指令并行调度,
vmulq_n_u16和vextq_u16可以在流水线中连续执行,而lane级操作更容易产生数据依赖,限制并行度。
额外优化建议:如果scenario1被多次调用且X内容固定,可以把构造好的查找表移到函数外预计算,避免每次调用重复构造,能进一步降低运行时间。
内容的提问来源于stack exchange,提问作者liwuen
相关产品推荐
相关产品推荐

