Gcc优化问题:无符号mod vs if分支

Gcc优化问题:无符号mod vs if分支,gcc,compiler-optimization,modulo,Gcc,Compiler Optimization,Modulo,我有一个在实时微控制器程序(ARM Cortex-M)中经常调用的函数(每秒至少40000次),它基本上在缓冲区的长度内保留一个计数器,而不是二的幂 因此,我可以选择以下两个选项之一: extern uint32_t x; void increment_MOD(void) { x = (x + 1) % 100; } 或 除非我错了,否则这两者在功能上似乎是等价的,所以: GCC将其中一个优化为更快的形式(无论是哪种形式)是否不正确? 看起来“如果”版本会更快,除非管道/分支预测失误

我有一个在实时微控制器程序(ARM Cortex-M)中经常调用的函数(每秒至少40000次),它基本上在缓冲区的长度内保留一个计数器,而不是二的幂

因此,我可以选择以下两个选项之一:

extern uint32_t x;

void increment_MOD(void)
{
    x = (x + 1) % 100;
}

除非我错了,否则这两者在功能上似乎是等价的,所以:

GCC将其中一个优化为更快的形式(无论是哪种形式)是否不正确?

看起来“如果”版本会更快,除非管道/分支预测失误是一个问题(但ARM Cortex-M CPU目前没有大型管道)


如果输入函数时
x
从未>99,则编译器无法从代码中知道优化无效。如果输入函数时带有
x=100
,则在函数退出时,如果带有If分支
x=0
,则在函数退出时递增\u If,而对于mod variant
increment\u mod
您会得到
x=1

优化是无效的,因为编译器无法从代码中知道,当输入函数时
x
永远不会>99。如果输入函数时带有
x=100
,则在函数退出时,如果带有If分支
x=0
,则在函数退出时递增\u If,而对于mod variant
increment\u mod
您会得到
x=1

,理论上,这将是一个有效的“仿佛”规则优化,但我不希望编译器实现它。请注意,您可能会使用自己的优化过程将自己的优化过程添加到GCC。但这需要很多努力。理论上,这将是一个根据“仿佛”规则进行的有效优化,但我不希望编译器实现它。请注意,您可以使用自己的优化过程将自己的优化过程添加到GCC。但这需要很多努力。
void increment_IF(void)
{
    uint32_t tmp = x + 1;
    if (tmp >= 100)
        tmp = 0;
    x = tmp;
}
// it's nice to see that % is implemented
// using multiplication and shifts

increment_MOD:
    ldr r1, .L2
    ldr r3, .L2+4
    ldr r2, [r1]
    add r2, r2, #1
    umull r0, r3, r2, r3
    lsr r3, r3, #5
    add r3, r3, r3, lsl #2
    add r3, r3, r3, lsl #2
    sub r3, r2, r3, lsl #2
    str r3, [r1]
    bx lr
.L2:
   .word x
   .word 1374389535

// this is the IF variant

increment_IF:
    ldr r2, .L6
    ldr r3, [r2]
    add r3, r3, #1
    cmp r3, #99
    movhi r3, #0
    str r3, [r2]
    bx lr
.L6:
    .word x