c++ - 如何让GCC编译器将变量除法转换为mul(如果更快)

标签 c++ gcc optimization division

int a, b;
scanf("%d %d", &a, &b);
printf("%d\n", (unsigned int)a/(unsigned char)b);

编译时,我得到了
...
    ::00401C1E::  C70424 24304000          MOV DWORD PTR [ESP],403024  %d %d
    ::00401C25::  E8 36FFFFFF              CALL 00401B60               scanf
    ::00401C2A::  0FB64C24 1C              MOVZX ECX,BYTE PTR [ESP+1C]
    ::00401C2F::  8B4424 18                MOV EAX,[ESP+18]                        
    ::00401C33::  31D2                     XOR EDX,EDX                             
    ::00401C35::  F7F1                     DIV ECX                                 
    ::00401C37::  894424 04                MOV [ESP+4],EAX                         
    ::00401C3B::  C70424 2A304000          MOV DWORD PTR [ESP],40302A  %d\x0A
    ::00401C42::  E8 21FFFFFF              CALL 00401B68               printf

如果将DIV转换为MUL并使用数组存储多值会更快吗?如果是这样,如何让编译器进行优化?
int main() {
    uint a, s=0, i, t;
    scanf("%d", &a);
    diviuint aa = a;
    t = clock();
    for (i=0; i<1000000000; i++)
        s += i/a;
    printf("Result:%10u\n", s);
    printf("Time:%12u\n", clock()-t);
    return 0;
}

其中diviuint(a)记为1 / a的内存并改用倍数
使用s + = i / aa使速度是s + = i / a的2倍

最佳答案

当在编译时知道其中一个值时,用MUL替换DIV可能很有意义(但不一定在所有情况下都可以)。当两者都是用户输入时,您不知道范围是多少,因此所有常规技巧都将失效。

基本上,您需要同时处理ab之间的INT_MAXINT_MIN。没有足够的空间来放大/缩小它们。即使您想将它们扩展为更大的类型,也可能需要更长的时间才能反转b并检查结果是否一致。

关于c++ - 如何让GCC编译器将变量除法转换为mul(如果更快),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36832440/

相关文章:

linux - 来自 gcc 的 pgo 的优化报告

mysql - 如何使用 ORDER BY RAND() 优化此 SQL 查询

c++ - 牡丹AES CBC PKCS7加解密

c++ - 无法在 QTableView 上检测到 "Keypress"?

gcc - gcc 链接时可以使用多核吗?

c - gcc 是否使用 v* 汇编指令给出更差/更慢的代码?

c++ - 如何使用 wchar_t 为 fmt 编写格式化程序?

c++ - 如何在“文件夹选择”对话框中将“我的音乐”作为默认选定路径

c++ - 在 Mac 上构建的 HPX 出现链接器错误

java - 快速乘法和减法取模素数