我想知道是否有人找到了一种比使用vmaxvq_s16() ARM neon Intrisic更有效(更快)的方法来查找int16x8向量中的最大值。例如,我试图从做一些矢量化比较中受益,但无法通过使用上面的intrisic更快地找到解决方案。
vmaxvq_s16()
cyvaqqii1#
正如评论中所指出的,vmaxvq的实现有相当多的延迟,甚至没有双重问题,但典型的替代方案甚至更糟。
vmaxvq
a = vmaxq_s16(a, vextq_s16(a,a,1)); a = vmaxq_s16(a, vextq_s16(a,a,2)); a = vmaxq_s16(a, vextq_s16(a,a,4));
a = vmaxq_s16(a, vextq_s16(a,a,1));
a = vmaxq_s16(a, vextq_s16(a,a,2));
a = vmaxq_s16(a, vextq_s16(a,a,4));
然而,ARM64通常更有效地实现成对最大值,允许
a = vpmaxq_s16(a, a); a = vpmaxq_s16(a, a); a = vpmaxq_s16(a, a);
a = vpmaxq_s16(a, a);
如果原来的问题不允许重组纯垂直操作,仍然有可能摊销并行的最大操作。
// the two first elements here will be garbage int16_t buffer[N + 2]; auto A = vdupq_n_s16(0); for (int i = 0; i < N; i++) { int16x8_t x = my_algorithm(); A = vpmaxq_s16(A, x); // <- just a single fast vpmax per iteration vst1q_lane_s16(buffer + i, A, 1); } // you need two more iterations to finish the pairwise horizontal // maximums that are partially stored in A for (int i = N; i < N + 2; i++) { A = vpmaxq_s16(A, A); vst1q_lane_s16(buffer + i, A, 1); }
// the two first elements here will be garbage
int16_t buffer[N + 2];
auto A = vdupq_n_s16(0);
for (int i = 0; i < N; i++) {
int16x8_t x = my_algorithm();
A = vpmaxq_s16(A, x); // <- just a single fast vpmax per iteration
vst1q_lane_s16(buffer + i, A, 1);
}
// you need two more iterations to finish the pairwise horizontal
// maximums that are partially stored in A
for (int i = N; i < N + 2; i++) {
A = vpmaxq_s16(A, A);
两次迭代的示例运行
A = 0 0 0 0 0 0 0 0, v_0 = 1 2 3 1 2 3 1 2 A = 0 0 0 0 3 4 5 3, v_1 = 0 1 0 2 3 2 0 0 A = 0 0 3+4 5+3 0+1 0+2 3+2 0+0, v_2 = ? ? ? ? ? ? ? ? ----------------- A = 0 [15] 3 5. ? ? ? ? [15 = 1+2+3+1+2+3+1+2] A = 15 [ 8] ? ? ? ? ? ? [8 = 0+1+0+2+3+2+0+0]
A = 0 0 0 0 0 0 0 0, v_0 = 1 2 3 1 2 3 1 2
A = 0 0 0 0 3 4 5 3, v_1 = 0 1 0 2 3 2 0 0
A = 0 0 3+4 5+3 0+1 0+2 3+2 0+0, v_2 = ? ? ? ? ? ? ? ?
-----------------
A = 0 [15] 3 5. ? ? ? ? [15 = 1+2+3+1+2+3+1+2]
A = 15 [ 8] ? ? ? ? ? ? [8 = 0+1+0+2+3+2+0+0]
第一个元素A[0]将btw累加所有元素的总最大值。
A[0]
1条答案
按热度按时间cyvaqqii1#
正如评论中所指出的,
vmaxvq
的实现有相当多的延迟,甚至没有双重问题,但典型的替代方案甚至更糟。然而,ARM64通常更有效地实现成对最大值,允许
如果原来的问题不允许重组纯垂直操作,仍然有可能摊销并行的最大操作。
两次迭代的示例运行
第一个元素
A[0]
将btw累加所有元素的总最大值。