请考虑以下代码:
unsigned long long div(unsigned long long a, unsigned long long b, unsigned long long c) {
unsigned __int128 d = (unsigned __int128)a*(unsigned __int128)b;
return d/c;
}
[当使用x86-64 gcc 10或clang 10编译时,都使用-O3
时,它是emits __udivti3
,而不是DIVQ
指令:
div:
mov rax, rdi
mov r8, rdx
sub rsp, 8
xor ecx, ecx
mul rsi
mov r9, rax
mov rsi, rdx
mov rdx, r8
mov rdi, r9
call __udivti3
add rsp, 8
ret
至少在我的测试中,前者比后来的(已经)慢得多,因此出现了问题:是否有办法使现代编译器为上述代码发出DIVQ
?
编辑:让我们假设商适合64位寄存器。
div
。您需要一个固有的或内联的asm来显式执行128/64位=> 64位除法。例如div
具有GNU C内联汇编,分别适合低/高半。
不幸的是,GNU C没有内在的特性。 MSVC确实有:Intrinsics for 128 multiplication and division有链接。