以下两个代码序列产生相同的结果:
uint mod = val % 4;
uint mod1 = val & 0x3;
我可以同时使用两者来计算相同的结果。我知道在硬件中,&
运算符比 %
运算符更容易实现。因此我希望它比 %
运算符有更好的性能。
我能否始终假设 &
具有更好或相等的性能?
编译器会自动优化吗?
最佳答案
您不能对这些操作中的任何一个进行任何假设,编译可以将两者优化为相同的指令。
而且,事实上,clang
和 gcc
都会将它们转换为单个 和
指令。
不幸的是,由于 %
的性质自 ISO C99 起具有指定的负值返回值,因此需要为 signed
整数做一些额外的工作。与 ISO C90 不同,负模是实现定义的。
两种操作的结果集,无论是signed
还是unsigned
值:
modulo
带符号整数:
mov eax, DWORD PTR [esp+4] ; grab `val`
cdq ; convert 32-bit EAX to 64-bit
; and fill EDX with the sign bit
shr edx, 30 ; shift EDX by 30 positions to the right
; leaving only the two left-most bits
add eax, edx ; add EDX to EAX
and eax, 3 ; do the AND
sub eax, edx ; subtract EDX from EAX
mov DWORD PTR [esp+8], eax ; move result on stack
这是一个巧妙的技巧,可以正确定义负值的行为。它对负值执行 ((val + 3) & 3) - 3
,对正值执行 val & 3
。
and
with signed/unsigned and modulo
with unsigned:
mov eax, DWORD PTR [esp+4]
and eax, 3
mov DWORD PTR [esp+12], eax
关于c - 是否存在 '&' 产生的性能低于 '%' 的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37180903/