以下两个代码序列产生相同的结果:
uint mod = val % 4;
uint mod1 = val & 0x3;
我可以使用两者来计算相同的结果。我知道在硬件中,
&
运算符比%
运算符实现起来简单得多。因此,我希望它比%
运算符具有更好的性能。我是否可以始终假设
&
具有更好或相等的性能?编译器会自动优化吗?
最佳答案
您不能对这些操作中的任何一个假设任何东西,编译可以将它们优化为相同的指令。
而且,的确,clang
和gcc
都会将它们转换为一条and
指令。
不幸的是,由于自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
:mov eax, DWORD PTR [esp+4]
and eax, 3
mov DWORD PTR [esp+12], eax
关于c - 是否存在 '&'的性能低于 '%'的情况?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37180903/