相关疑难解决方法(0)

C和C++优化器通常知道哪些函数没有副作用?

比如非常常见的数学函数,例如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;
}
Run Code Online (Sandbox Code Playgroud)

如果他们可以,有没有办法声明一个函数没有副作用,因此可以安全地以这种方式进行优化?VS2010应用程序的初始分析表明优化是有益的.

另请参阅这个相关的问题,这个问题很接近但不能完全回答我自己的问题.

编辑:一些很棒的答案.我接受的那个基于它作为答案本身引起的评论,特别是链接的文章,以及在errno设定的情况下(即副作用)可能不会发生提升的事实.因此,在我正在做的事情的背景下,这种类型的手动优化似乎仍然有意义.

c c++ optimization

42
推荐指数
4
解决办法
2225
查看次数

不同编译器中的pure/const函数属性

pure是一个函数属性,表示函数不会修改任何全局内存.
const是一个函数属性,表示函数不读取/修改任何全局内存.

鉴于该信息,编译器可以进行一些额外的优化.

GCC示例:

float sigmoid(float x) __attribute__ ((const));

float calculate(float x, unsigned int C) {
    float sum = 0;
    for(unsigned int i = 0; i < C; ++i)
        sum += sigmoid(x);
    return sum;
}

float sigmoid(float x) { return 1.0f / (1.0f - exp(-x)); }
Run Code Online (Sandbox Code Playgroud)

在该示例中,编译器可以将函数计算优化为:

float calculate(float x, unsigned int C) {
    float sum = 0;
    float temp = C ? sigmoid(x) : 0.0f;
    for(unsigned int i = 0; i < C; ++i)
        sum …
Run Code Online (Sandbox Code Playgroud)

c++ gcc const function-attributes

32
推荐指数
2
解决办法
8710
查看次数

分配内存然后释放是否构成C++程序的副作用?

受此问题的启发,关于编译器是否可以优化掉对函数的调用而没有副作用.假设我有以下代码:

delete[] new char[10];
Run Code Online (Sandbox Code Playgroud)

它没有任何用处.但它有副作用吗?堆分配后立即释放被认为是副作用吗?

c++ memory memory-management

11
推荐指数
1
解决办法
396
查看次数