是否有'&'的情况产生的性能低于'%'?

时间:2016-05-12 08:07:54

标签: c performance modulo bitwise-and

以下两个代码序列产生相同的结果:

uint mod = val % 4;

uint mod1 = val & 0x3;

我可以用两者来计算相同的结果。我知道在硬件中&运算符比%运算符更简单。因此,我希望它的性能优于%运算符。

我是否可以始终认为&具有更好或相同的性能? 编译器会自动优化吗?

2 个答案:

答案 0 :(得分:8)

你不能假设这些操作中的任何一个,编译可以优化两个相同的指令。

事实上,clanggcc都会将它们转换为单个and指令。

不幸的是,由于%具有自ISO C99以来负值的指定返回值的性质,signed整数需要一些额外的工作。与ISO C90相反,其中负模数是实现定义的。

两个操作的结果程序集,signedunsigned值:

带有签名整数的

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和未签名的modulo

mov     eax, DWORD PTR [esp+4]
and     eax, 3
mov     DWORD PTR [esp+12], eax

答案 1 :(得分:1)

(现代)编译器应该从您的示例生成相同的代码,并且这种优化的原因是rhs是编译常量。

据我所知,&运算符是用一个处理器指令and完成的;模数运算符的情况并非如此,它通常意味着更多的运算(计算整数除法的余数)。 AFAIK,它通常比乘法长;我认为它只要是一个整数除法。