如果使用临时变量进行索引,则会更慢?

时间:2014-07-01 08:48:10

标签: c++ loops

我正在用C ++阅读与数学相关的源代码。在下面的示例中,有很多循环类似于第一个循环。如果我存储一些临时变量用于索引,我认为它们可以更有效。但是,我错了。

我打算存储i * 8的结果,以减少乘法次数。以下示例已简化。原案可能更复杂。 我是否努力减少与此类似的情况下无效的乘法次数?

// Without register
Old
Time: 8.8
New
Time: 9.0

与我的直觉相反,如果我使用临时变量,速度会慢一些!


然后我使用register存储临时变量,如果我使用临时变量,结果会更快。

// With register
Old
Time: 8.9
New
Time: 7.8

如果编写涉及大量计算的速度密集型应用程序,我应该依靠编译器优化还是register?如果是多线程,register会导致任何问题吗?


#include <cstdio>
#include <ctime>

#define DIM 10000
#define COUNT 100000
int main() {
  clock_t start, end;
  double mtx[8 * DIM] = {0};
  printf("Old\n");
  start = clock();
  for (int count = 0; count < COUNT; ++count) {
    for (int i = 0; i < DIM; ++i) {
      mtx[i * 8 + 0] += 1;
      mtx[i * 8 + 1] += 1;
      mtx[i * 8 + 2] += 1;
      mtx[i * 8 + 3] += 1;
      mtx[i * 8 + 4] += 1;
      mtx[i * 8 + 5] += 1;
      mtx[i * 8 + 6] += 1;
      mtx[i * 8 + 7] += 1;
    }
  }
  end = clock();
  printf("Time: %2.1lf\n", (double)(end - start) / CLOCKS_PER_SEC);

  printf("New\n");
  start = clock();
  /* register */ int j;
  for (int count = 0; count < COUNT; ++count) {
    for (int i = 0; i < DIM; ++i) {
      j = i * 8;
      mtx[j + 0] += 1;
      mtx[j + 1] += 1;
      mtx[j + 2] += 1;
      mtx[j + 3] += 1;
      mtx[j + 4] += 1;
      mtx[j + 5] += 1;
      mtx[j + 6] += 1;
      mtx[j + 7] += 1;
    }
  }
  end = clock();
  printf("Time: %2.1lf\n", (double)(end - start) / CLOCKS_PER_SEC);
  return 0;
}

我不熟悉g++的命令行选项。我在上面的例子中使用了g++ efficiency.cpp。然后,我尝试了-O2选项,在两种情况下消耗的时间都减少到0.0

1 个答案:

答案 0 :(得分:2)

我正在解释以下内容构成您的问题。

  

如果编写一个涉及大量计算的速度密集型应用程序   这样,我应该依靠编译器或寄存器的优化吗?如果   多线程,会注册导致任何问题吗?

首先,如果您的目标是(并尝试衡量)程序的效率,那么如果不是-O2,则应始终至少运行-O3,具体取决于所使用的内容生产

在编译器完成了它可以做的一切之后,你可以然后考虑手动优化,例如使用register变量。大多数情况下,您会发现编译器忽略了register关键字,或者对性能没有显着帮助。

多线程是否会导致register使用出现任何问题的简短回答是。话虽如此,即使没有register,也有很多方法可以编写不正确的多线程程序。


问题中提到的相关问题:当​​您使用优化运行时,为什么您的时序都接近于零?

如果编译器可以通过静态分析确定从不使用循环的结果,或者循环本身可以被更简单的计算替换(可能直接添加COUNT),那么它将继续这样做,这将大大减少时间。

唯一可以确定的方法是使用gcc -S -O2在特定优化后显示程序集,并从程序集中确定循环是否仍然存在。