我正在用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
。
答案 0 :(得分:2)
我正在解释以下内容构成您的问题。
如果编写一个涉及大量计算的速度密集型应用程序 这样,我应该依靠编译器或寄存器的优化吗?如果 多线程,会注册导致任何问题吗?
首先,如果您的目标是(并尝试衡量)程序的效率,那么如果不是-O2
,则应始终至少运行-O3
,具体取决于所使用的内容生产
在编译器完成了它可以做的一切之后,你可以然后考虑手动优化,例如使用register
变量。大多数情况下,您会发现编译器忽略了register
关键字,或者对性能没有显着帮助。
多线程是否会导致register
使用出现任何问题的简短回答是否。话虽如此,即使没有register
,也有很多方法可以编写不正确的多线程程序。
问题中提到的相关问题:当您使用优化运行时,为什么您的时序都接近于零?
如果编译器可以通过静态分析确定从不使用循环的结果,或者循环本身可以被更简单的计算替换(可能直接添加COUNT
),那么它将继续这样做,这将大大减少时间。
唯一可以确定的方法是使用gcc -S -O2
在特定优化后显示程序集,并从程序集中确定循环是否仍然存在。