У меня есть функция, которая очень часто вызывается в программе микроконтроллера в реальном времени (ARM Cortex-M) (по крайней мере, 40000 раз в секунду), и она в основном держит счетчик внутри длины буфера, который не являетсястепень двух.
Таким образом, у меня может быть один из этих двух вариантов:
extern uint32_t x;
void increment_MOD(void)
{
x = (x + 1) % 100;
}
или
void increment_IF(void)
{
uint32_t tmp = x + 1;
if (tmp >= 100)
tmp = 0;
x = tmp;
}
Эти два кажутся функционально эквивалентными, если я не ошибаюсь, поэтому:
Было бы неправильно для GCC оптимизировать один из них в более быструю форму (какая бы она ни была)?
Похоже, что версия "if"по-прежнему будет быстрее, если только проблема с неправильным прогнозом конвейера / ветви не является проблемой (но у процессора ARM Cortex-M нет больших конвейеров AFAIK).
// 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