发出DIV指令,而不是__udivti3

问题描述 投票:1回答:1

请考虑以下代码:

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位寄存器。

c gcc optimization clang x86-64
1个回答
0
投票
即使您确实向编译器提供了足够的信息以找出该除法器不会溢出,但是不幸的是,gcc / clang仍然不会将其优化为具有非零的高半数除数(RDX)的div

您需要一个固有的或内联的asm来显式执行128/64位=> 64位除法。例如div具有GNU C内联汇编,分别适合低/高半。

不幸的是,GNU C没有内在的特性。 MSVC确实有:Intrinsics for 128 multiplication and division有链接。

© www.soinside.com 2019 - 2024. All rights reserved.