Sch*_*lle 2 c performance modulo bitwise-and
以下两个代码序列产生相同的结果:
uint mod = val % 4;
uint mod1 = val & 0x3;
Run Code Online (Sandbox Code Playgroud)
我可以用两者来计算相同的结果.我知道在硬件中,&操作员比%操作员更容易实现.因此我希望它比%运营商有更好的性能.
我可以一直认为&性能更好或相同吗?编译器会自动优化吗?
您不能假设这些操作中的任何一个,编译可以优化两个相同的指令.
而且,事实上,无论是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
Run Code Online (Sandbox Code Playgroud)
这是一个巧妙的技巧,为负值正确定义行为.它正在((val + 3) & 3) - 3为负值而且val & 3为正面.
and签名/未签名和modulo未签名:
mov eax, DWORD PTR [esp+4]
and eax, 3
mov DWORD PTR [esp+12], eax
Run Code Online (Sandbox Code Playgroud)