我试图在基于Cortex-M的微控制器上钳制-127到127之间的值.
我有两个竞争功能,一个使用条件,另一个使用我在这里找到的无分支黑客.
// Using conditional statements
int clamp(int val) { return ((val > 127) ? 127 : (val < -127) ? -127 : val); }
// Using branchless hacks
int clamp(int val) {
val -= -127;
val &= (~val) >> 31;
val += -127;
val -= 127;
val &= val >> 31;
val += 127;
return val;
}
Run Code Online (Sandbox Code Playgroud)
现在我知道在某些情况下,这些方法中的一种可能比另一种方法更快,反之亦然,但总的来说使用无分支技术是值得的,因为它对我来说并不重要,我们都会使用在我的情况下工作得很好?
微控制器的一个小背景,它是一个基于ARM的微控制器,运行速度为90 MIPS,具有3级流水线,取指,解码和执行,它似乎有某种分支预测器,但我无法挖掘细节.
ARM 代码(GCC 4.6.3 带-O3):
clamp1:
mvn r3, #126
cmp r0, r3
movlt r0, r3
cmp r0, #127
movge r0, #127
bx lr
clamp2:
add r0, r0, #127
mvn r3, r0
and r0, r0, r3, asr #31
sub r0, r0, #254
and r0, r0, r0, asr #31
add r0, r0, #127
bx lr
Run Code Online (Sandbox Code Playgroud)
拇指代码:
clamp1:
mvn r3, #126
cmp r0, r3
it lt
movlt r0, r3
cmp r0, #127
it ge
movge r0, #127
bx lr
clamp2:
adds r0, r0, #127
mvns r3, r0
and r0, r0, r3, asr #31
subs r0, r0, #254
and r0, r0, r0, asr #31
adds r0, r0, #127
bx lr
Run Code Online (Sandbox Code Playgroud)
由于 ARM 的条件执行设计,两者都是无分支的。我敢打赌,它们在性能上基本上是可比的。
| 归档时间: |
|
| 查看次数: |
649 次 |
| 最近记录: |