C这个无分支的黑客实际上更快吗?

Cod*_*ith 7 c

我试图在基于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级流水线,取指,解码和执行,它似乎有某种分支预测器,但我无法挖掘细节.

nne*_*neo 4

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 的条件执行设计,两者都是无分支的。我敢打赌,它们在性能上基本上是可比的。