循环 - 存储数据或重新计算

时间:2013-08-30 15:34:08

标签: c++ loops data-storage

保存价值需要花多少时间来处理老虎机?假设我有一个计算值x,我将使用2次,5次或20次。在每次使用它时,保存计算值而不是重新计算它会更加优化到什么程度? 例如:

int a=0,b=-5;
for(int i=0;i<k;++i)
  a+=abs(b);

int a=0,b=-5;
int x=abs(b);
for(int i=0;i<k;++i)
  a+=x;

第二种情况在什么k值下产生更好的结果?此外,这个RAM依赖多少?

5 个答案:

答案 0 :(得分:3)

由于abs(b)的值在for循环内没有变化,编译器很可能会将两个片段优化为相同的结果,即只评估一次abs(b)的值。

答案 1 :(得分:1)

在真实场景中提供度量以外的答案几乎是不可能的。当您在代码中缓存数据时,它可能存储在寄存器中(在您提供的代码中很可能是),或者它可能被刷新到L1缓存或L2缓存...取决于循环是什么做(它使用了多少数据?)。如果该值缓存在寄存器中,则成本为0,推送得越远,检索该值所需的成本就越高。

通常,编写易于阅读和维护的代码,然后测量应用程序的性能,如果不好,请编写配置文件。找到热点,找到他们为什么是热点,然后从那里开始工作。我怀疑缓存与计算abs(x)的内容如上所述将成为真实应用程序中的热点。所以不要出汗。

答案 2 :(得分:0)

我会建议(这是没有测试你的心思)那个例子     int x=abs(b) 循环外部会更快,因为你为了调用abs()而避免在每次迭代时分配一个堆栈帧。

话虽如此,如果编译器足够聪明,它可能会弄清楚你正在做什么并为两者生成相同(或类似)的指令。

答案 3 :(得分:0)

根据经验,在循环外存储该值不会花费太多(如果有的话),因为编译器很可能无论如何都要将abs(x)的结果存储到寄存器中。事实上,当编译器优化此代码时(假设您已启用优化),它将要做的第一件事就是将abs(x)拉出循环。

您可以通过使用“register”提示限定“x”声明来进一步帮助编译器生成良好的代码。如果可能,这将要求编译器将x存储到寄存器值中。

如果你想看看编译器实际上对你的代码做了什么,要做的一件事是告诉它编译而不是汇编(在gcc中,选项是-S)并查看生成的汇编代码。在许多情况下,编译器将生成比手动优化更好的代码。但是,也没有理由不自己做这些简单的优化。

附录:

在GCC中启用优化的情况下编译上述代码将导致代码等效于:

a = abs(b) * k;

试一试,看看。

答案 4 :(得分:0)

对于许多情况,它从k = 2产生更好的性能。你给出的例子是。不是一个。即使启用了低级别的优化,大多数编译器也会尝试执行此类提升。在最坏的情况下,该值存储在本地堆栈中,因此可能会保持缓存温度,从而消除您的内存问题。

但可能会将其保存在登记簿中。

原件必须执行adittional分支,重复计算并返回值。 Abs是编译器可以识别为constexpr和hoist的函数的一个示例。

在开发自己的类时,这是您应尽可能将成员和引用标记为construe的原因之一。