我已经减少了我的代码下到下面,这很简单,只要我能把它同时保留了编译器输出我感兴趣。编译器指令重新排序用C++优化(什么阻碍他们)
void foo(const uint64_t used)
{
uint64_t ar[100];
for(int i = 0; i < 100; ++i)
{
ar[i] = some_global_array[i];
}
const uint64_t mask = ar[0];
if((used & mask) != 0)
{
return;
}
bar(ar); // Not inlined
}
将VC10与/ O2和/ Ob1一起使用,生成的程序集几乎反映了上述C++代码中指令的顺序。由于本地数组ar
只在条件失败时才传递给bar()
,否则我不希望编译器优化到如下所示。
if((used & some_global_array[0]) != 0)
{
return;
}
// Now do the copying to ar and call bar(ar)...
是编译器不这样做,因为它只是太难为它在一般情况下,识别此类优化?还是遵循一些严格的规定,禁止它这样做?如果是这样,为什么,有什么办法可以给我一个暗示,这样做不会改变我的程序的语义?
注:显然这将是微不足道的只是重新安排代码,即可获得最优化的输出,但我在很感兴趣,为什么编译器不会在这样的情况下优化,不如何在这个这么做(故意简化)的情况。
我认为“严格规定”不好措辞,我想我真的问的是,因为它被允许为所欲为,只要它能够确定它是不会改变程序逻辑,有没有一些具体的事情在这种情况下,防止它假设没有分配给本地阵列的副作用,哪一个控制路径刚丢弃而不使用?如果答案仅仅是在一般情况下很困难,那就够公平的了,这对我来说只是令人惊讶,因为这似乎是最容易检测的事情之一。 – kamrann 2012-02-25 09:13:39
我能想到的唯一的事情是编译器无法知道是否会与其他线程发生可能的交互,尤其是与全局数组。 – 2012-02-25 09:25:16
因此,一个更简化的案例仍然没有在任何主要编译器上得到优化,[根据LLVM家伙](http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-February/047750 .html)在一般情况下,就像你所说的那样,这太简单了。 – kamrann 2012-02-27 23:33:37