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);
如果原来的问题不允许重组纯垂直操作,仍然有可能摊销并行的最大操作。
// 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);
}
1条答案
按热度按时间cyvaqqii1#
正如评论中所指出的,
vmaxvq
的实现有相当多的延迟,甚至没有双重问题,但典型的替代方案甚至更糟。然而,ARM64通常更有效地实现成对最大值,允许
如果原来的问题不允许重组纯垂直操作,仍然有可能摊销并行的最大操作。
两次迭代的示例运行
第一个元素
A[0]
将btw累加所有元素的总最大值。