C++优化简单循环

标签 c++ optimization

我正在使用 Visual Studio 2012 并在 x64 Release模式上构建。下面的代码占用了我程序运行所需时间的 33.5%。我使用 Visual Studio Profiler 对其进行了测量。

    //every variable is unsigned int or unsigned int*

    for(unsigned int i = 0; i < num; i++)
    {
        unique[ids[i]]++;//2.1%
        total[ids[i]] += main_list[id];//31.4%
    }

有人可以推荐一种方法来减少此功能的运行时间吗?

编辑:根据您的输入,我尝试了以下代码:

    const unsigned int now = main_list[id];

    for(unsigned int i = ids[0], j = 0; j < num; j++)
    {
        ++unique[i];//2.0%
        total[i] += now;//16.7%
        i = ids[j];//16.8%
    }

这证实了 CPU 分支预测可能失败的理论,因为位置是随机的(顺便说一句,它们不是完全随机的,而是经过排序的)。请问是否可以加快我的代码速度?

第二次编辑:我尝试了以下操作:

    const unsigned int now = main_list[id];

    for(unsigned int i = ids[0], j = 0; j < num; j++)
    {
        total[i] += now;//2.0%
        ++unique[i];//16.7%
        i = ids[j];//16.8%
    }

上面的测试应该很清楚发生了什么。

最佳答案

您的代码没有任何地方友好性。我会抛出两个可能的想法。

  1. uniquetotal 组合在一起。

    struct Stuff {
        unsigned int unique, total;
    };
    
    for(unsigned int i = 0; i < num; i++)
    {
        Stuff& s = stuffs[ids[i]];
        s.unique++;
        s.total += main_list[id]; // <== is this supposed to be ids[i]?
    }
    

这将确保您在内存中连续访问的内容实际上在内存中彼此相邻。按原样,假设 num 足够大,那么每一行都缺少缓存。那是您所能得到的最糟糕的情况。

  1. 排序 ids。现在,你还在内存中蹦蹦跳跳。让我们确保我们实际上可以按顺序进行:

    std::sort(ids, ids + num);
    // rest of loop as before
    

这样,当您处理 stuffs[ids[i]] 时,stuffs[ids[i+1]] 很可能会被预取。这也会为您节省大量查找时间。

关于C++优化简单循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32361994/

相关文章:

c++ - 在 c/c++ 中提取算术表达式中的项

c++ - Debian 上的 Armel 交叉编译(工具链存储库问题)

unix - 为什么我不应该使用查找优化?

javascript - 根据覆盖率报告删除未使用的 javascript 代码

java - Android - 优化多个if语句

java - C++ 模板的 Java 等价物是什么?

c++ - 检测 win32 服务创建和删除的最佳方法

c++ - std::thread 到 std::async 会带来巨大的性能提升。怎么可能?

multithreading - 线程 : worth it for this situation?

java - 如何保持列表不 fragment 化(阅读解释)