我已經減少了我的代碼下到下面,這很簡單,只要我能把它同時保留了編譯器輸出我感興趣。編譯器指令重新排序用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