【发布时间】:2013-04-20 10:54:03
【问题描述】:
对于非常常见的数学函数,例如 sin、cos 等...编译器是否意识到它们没有副作用并有能力将它们移到外循环?例如
// Unoptimized
double YSinX(double x,int y)
{
double total = 0.0;
for (int i = 0; i < y; i++)
total += sin(x);
return total;
}
// Manually optimized
double YSinX(double x,int y)
{
double total = 0.0, sinx = sin(x);
for (int i = 0; i < y; i++)
total += sinx;
return total;
}
如果可以,有没有一种方法可以将函数声明为没有副作用,从而可以安全地以这种方式进行优化? VS2010 应用程序的初始分析表明优化是有益的。
另请参阅此related question,它很接近但并不能完全回答我自己的问题。
编辑:一些很棒的答案。我接受的那个是基于它引发的 cmets 和答案本身,特别是链接的文章,以及在设置 errno 的情况下可能不会发生提升的事实(即副作用)。因此,在我正在做的事情的背景下,这种类型的手动优化似乎仍然有意义。
【问题讨论】:
-
它是特定于编译器的,但我在 gcc 文档的某处看到了
pure属性。 -
@RogerRowland:它没有。考虑修改单例状态或可变变量
-
这是我平时做的一种优化不依赖编译器来做。手动完成通常很容易,因此几乎不需要让自己受制于编译器——它会受到许多其他因素的影响。
-
@Mysticial 我同意。您可以安全地做到这一点,而不会污染封闭范围
for(size_t i = 0, end = foo.size(); i < end; ++i).。 -
@Koushik:我们这里说的优化其实是提升;但是,正如所指出的,您只能在执行一次函数并缓存其结果时才能提升函数,并产生与每次迭代执行时相同的输出。
标签: c++ c optimization