我手写的取模:
// #define MOD 2147483647
inline unsigned MODDD(ull x){
x = (x&MOD) + (x >> 31);
if(x > MOD) x = (x&MOD) + (x >> 31);
if(x > MOD) x -= MOD;
return x;
}
正常的取模:
inline unsigned MODDD(ull x){
return x%MOD;
}
本来以为手写的会快一点,但没想到正常版更快
于是去 Compiler Explorer 看了它们的汇编
手写版:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
and eax, 2147483647
mov rdx, rax
mov rax, QWORD PTR [rbp-8]
shr rax, 31
add rax, rdx
mov QWORD PTR [rbp-8], rax
mov eax, 2147483648
cmp QWORD PTR [rbp-8], rax
jb .L2
mov rax, QWORD PTR [rbp-8]
and eax, 2147483647
mov rdx, rax
mov rax, QWORD PTR [rbp-8]
shr rax, 31
add rax, rdx
mov QWORD PTR [rbp-8], rax
.L2:
mov eax, 2147483648
cmp QWORD PTR [rbp-8], rax
jb .L3
sub QWORD PTR [rbp-8], 2147483647
.L3:
mov rax, QWORD PTR [rbp-8]
pop rbp
ret
正常版:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov rcx, QWORD PTR [rbp-8]
movabs rdx, 8589934597
mov rax, rcx
mul rdx
mov rax, rcx
sub rax, rdx
shr rax
add rax, rdx
shr rax, 30
mov rdx, rax
sal rdx, 31
sub rdx, rax
mov rax, rcx
sub rax, rdx
pop rbp
ret
那么,编译器优化正常版的原理是什么,以及手写能不能达到这样的效果/yiw
悬关orz