c ++嵌套循环性能

时间:2014-11-26 08:00:34

标签: c++ performance loops

我基本上有两个向量,一个用于大量元素,另一个用于少量用于对元素数据进行采样的探测器。我偶然发现了实现两个循环的顺序问题。当然,我认为在较大的向量上有外环将是有益的

实施1:

for(auto& elem: elements) {
    for(auto& probe: probes) {
        probe.insertParticleData(elem);
    }
}

然而,似乎第二次实施只需要一半的时间

实施2:

for(auto& probe: probes) {
    for(auto& elem: elements) {
        probe.insertParticleData(elem);
    }
}

可能是什么原因?

修改

通过以下代码生成计时

clock_t t_begin_ps = std::clock();
... // timed code
clock_t t_end_ps = std::clock();
double elapsed_secs_ps = double(t_end_ps - t_begin_ps) / CLOCKS_PER_SEC;

并且在插入元素数据时我基本上做了两件事,测试到探针的距离是否低于限制并计算平均值

probe::insertParticleData (const elem& pP) {
   if (!isInside(pP.position())) {return false;}
   ... // compute alpha and beta
   avg_vel = alpha*avg_vel + beta*pP.getVel();
   return true;
}

要了解我有大约的内存使用情况。 10k元素,它们是具有30个双数据成员的对象。对于测试,我使用了10个含有15个双打的探针。

2 个答案:

答案 0 :(得分:4)

今天的CPU经过大量优化,可以线性访问内存。因此,一些长循环将击败许多短循环。您希望内部循环迭代长向量。

答案 1 :(得分:2)

我的猜测: 如果insertParticleData是虚拟的,编译器会将函数的地址视为内部循环中的常量,并将vtable fetch移动到内部循环之外。 即有效地生成如下代码:

   for (auto& probe: probes) {
      funcPtr p = probe.insertParticleData;
      for (auto& elem: elements) {
        (*p)(elem);
      }
   }

而在第一个版本中,p将为每次内部迭代计算。