簡體   English   中英

為什么編譯器不優化這種初始化?

[英]Why does the compiler not optimize this initialization?

考慮以下C代碼:

extern void foo(int* ip);

void myfunc(void)
{
    int arr[15] = {0};
    for (int i=0; i<10; i++)
    {
        arr[i] = 42;
    }

    foo(arr);
}

我嘗試使用gcc和clang,使用-O3-Os 在所有情況下,編譯的程序集在用42覆蓋其中10個之前寫入所有15個零。

我想可能只是沒有針對這個案例編寫優化,但對我來說這似乎是一個相當明顯和常見的情況。 有沒有阻止優化的東西?

我在x86-32 Linux上使用這些命令:

gcc -std=c99 -S -O3 hello.c
clang -std=c99 -S -O3 hello.c

這不是一個非常科學的解釋,而只是一種直覺(但是,我確實碰巧知道GCC的一些內部結構)。

為了可靠地進行所需的優化,編譯器必須管理子數組切片 然后它變得非常復雜且容易出錯。 優化那么多的編譯器可能會占用大量內存(用於子數組的符號表示)和大量的編譯時間。 這通常不值得努力(最好在編譯器內部優化循環)。

順便說一下,GCC有一個插件框架和MELT擴展(MELT是一個擴展GCC的lispy域特定語言,我是MELT的主要作者)。 因此,您可以嘗試添加新的優化傳遞(通過MELT擴展或某些C ++插件)來完成工作。 你很快就會意識到你的傳遞要么非常具體,要么需要處理大量的GCC內部表示,並且很可能會破壞編譯時間和內存以獲得極少的收益。

請注意,GCC和Clang都巧妙地展開了兩個循環(這在很大程度上取決於性能)。

順便說一句, Frama-C (由同事開發的C程序的靜態分析器)值分析器似乎能夠推斷出關於你的arr良好屬性

因此,請隨意將該優化添加到GCC。 如果您不知道(或沒有時間 - 許多個月或幾年)如何添加它,請隨時向能夠根據您的需求增強GCC的公司或組織付款。 可能需要一百萬歐元(或美元)/ 3年的項目來完成有趣案例的優化工作。

如果您認真考慮花這么多錢,請通過電子郵件與我聯系。

具有這種優化的編譯器需要一些啟發式來禁用它們(例如,如果arr是一個百萬個成員的數組,並且你編寫了一些Erasthothenes的篩子,編譯器努力保留所有子切片的聯合可能是不值得的。編譯時的復合索引)

順便說一句,你會接受一個20倍慢的優化編譯器(在編譯時更慢)獲得一個增益(在運行時可能只有一小部分),這在實踐中很少發生並且不是很重要嗎? 最后,我不認為這是優化的常見情況 因人而異。

您可能對源代碼變換器PIPS4U感興趣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM