为什么我的C++编译器没有优化这些内存写入?

Jos*_*der 4 c++ optimization

我创建了这个程序.它没有任何兴趣,但使用处理能力.

查看输出objdump -d,即使用O3编译,我也可以看到接近结束的三个rand调用和相应的mov指令.

为什么编译器没有意识到内存不会被使用而只是替换下半部分while(1){}?我正在使用gcc,但我最感兴趣的是标准所要求的内容.

/*
 * Create a program that does nothing except slow down the computer.
 */
#include <cstdlib>
#include <unistd.h>

int getRand(int max) {
  return rand() % max;
}

int main() {
  for (int thread = 0; thread < 5; thread++) {
    fork();
  }
  int len = 1000;
  int *garbage = (int*)malloc(sizeof(int)*len);
  for (int x = 0; x < len; x++) {
    garbage[x] = x;
  }
  while (true) {
    garbage[getRand(len)] = garbage[getRand(len)] - garbage[getRand(len)];
  }
}
Run Code Online (Sandbox Code Playgroud)

int*_*jay 10

因为GCC不够智能,无法在动态分配的内存上执行此优化.但是,如果您更改garbage为本地数组,GCC会将循环编译为:

.L4:
    call    rand
    call    rand
    call    rand
    jmp .L4
Run Code Online (Sandbox Code Playgroud)

这只是rand重复调用(这是必需的,因为调用有副作用),但优化了读写.

如果GCC更智能,它也可以优化rand呼叫,因为它的副作用只影响以后的任何rand呼叫,在这种情况下没有任何.但是,这种优化可能会浪费编译器编写者的时间.


Ala*_*kes 5

通常,它不能告诉我rand()这里没有可观察到的副作用,并且不需要删除这些调用.

它可以删除写入,但可能是使用数组足以抑制它.

该标准既不要求也不禁止它正在做什么.只要程序具有正确的可观察行为,任何优化都纯粹是实现的质量问题.