假设我有两个uint16_t[4]
数组a
和b
,数组中的每个整数都在[0,16383]范围内,所以第14位和第15位没有设置,然后我用一些代码来查找x1m5 n1,在a[i]
和b[i]
中的最小值和最大值:
uint16_t min[4], max[4];
for (int i = 0; i < 4; i++) {
if (a[i] < b[i]) {
min[i] = a[i];
max[i] = b[i];
} else {
min[i] = b[i];
max[i] = a[i];
}
}
假设由于某种原因,我不能/不愿使用SIMD,但我仍然希望在64位平台上尽可能快地进行计算,因此,自然的解决方案是在64位寄存器上使用单寄存器内SIMD(SWAR)范例,在单次迭代中计算这4个值,而不是使用16位算法进行4次迭代。
使用SWAR范例时,可以使用哪些位处理技巧来实现(min或max)操作,或者理想情况下同时实现这两种操作,从而使生成的代码比上面的循环更快?我的目标架构是ARMv 8,因此可以随意使用任何有助于减少指令数的ARMv 8指令。
汇编或C +内联汇编解决方案都是受欢迎的。
1条答案
按热度按时间c3frrgcw1#
您可以使用这样的代码,尽管它实际上比使用SIMD要长得多:
该算法的关键路径有6条指令,
不在关键路径上。如果在循环中执行,则可能会提升恒定负载。最后两条指令可以独立评估,以相同的延迟产生最小值和最大值。