簡體   English   中英

在比較Java與C ++的速度時,應該使用-O3或-O2編譯C ++代碼嗎?

[英]When comparing Java with C++ for speed should I compile the C++ code with -O3 or -O2?

我正在用Java和C ++編寫各種等效程序,以比較兩種語言的速度。 這些程序在循環中進行大量的數學計算。

有趣的是,當我使用-O3時,我發現C ++擊敗了Java。 當我使用-O2 Java勝過C ++。

我應該使用哪種g ++編譯器優化來得出我的比較結論?

我知道這並不像聽起來那么簡單,但是我想對Java和C ++之間的延遲/速度比較有一些見解。

有趣的是,當我使用-O3時,我發現C ++擊敗了Java。 當我使用-O2時,Java勝過C ++。

-O3在微基准測試中肯定會勝過-O2 ,但是當您對更實際的應用程序(例如FIX引擎)進行基准測試時,您會發現-O2在性能方面勝過-O3

據我所知, -O3在編譯小型和數學代碼方面做得很好,但是對於更現實和較大的應用程序,它實際上可能比-O2慢。 通過嘗試積極地優化所有內容(即內聯,向量化等),編譯器將產生大量二進制文件,從而導致cpu緩存未命中(即尤其是指令緩存未命中)。 這是Hotspot JIT選擇不優化大型方法和/或非熱點方法的原因之一。

需要注意的重要一件事是,JIT使用方法作為有資格進行優化的獨立單元 先前的問題中 ,您具有以下代碼:

int iterations = stoi(argv[1]);
int load = stoi(argv[2]);

long long x = 0;

for(int i = 0; i < iterations; i++) {

    long start = get_nano_ts(); // START clock

    for(int j = 0; j < load; j++) {
        if (i % 4 == 0) {
            x += (i % 4) * (i % 8);
        } else {
            x -= (i % 16) * (i % 32);
        }
    }

    long end = get_nano_ts(); // STOP clock

    // (omitted for clarity)
}

cout << "My result: " << x << endl;  

但是,此代碼對JIT不友好,因為代碼的熱塊不在其自己的方法中 為了獲得主要的JIT,您應該使用自己的方法將代碼塊放入循環內。 您的方法執行熱代碼塊而不是熱方法 包含for循環的方法可能僅被調用一次,因此JIT對此不會做任何事情。

在比較Java與C ++的速度時,應該使用-O3或-O2編譯C ++代碼嗎?

好吧,如果將-O3用於微基准測試,您將獲得驚人的快速結果,這對於大型和更復雜的應用程序將是不現實的。 這就是為什么我認為法官使用-O2而不是-O3 例如, 我們的無垃圾Java FIX引擎比C ++ FIX引擎快,並且我不知道它們是使用-O0-O1-O2-O3還是通過可執行鏈接混合使用它們。

從理論上講,一個人可以有選擇地將整個C ++應用程序划分為可執行文件,選擇哪些將使用-O2進行編譯,以及哪些將使用-O3進行編譯。 然后將所有內容鏈接到理想的二進制可執行文件中。 但是實際上,這有多可行?

熱點選擇的方法要簡單得多。 它說:

聽着,我將每種方法視為獨立的執行單元,而不是任何地方的任何代碼塊。 如果該方法足夠熱(即經常調用)並且足夠小,我將嘗試積極優化它。

當然,這樣做的缺點是需要進行代碼預熱,但它要簡單得多,並且在大多數情況下對於實際/大型/復雜的應用程序會產生最佳結果。

最后但並非最不重要的一點是,如果要使用-O3編譯整個應用程序,則應該考慮以下問題: 什么時候可以放心地使用-O3編譯程序?

如果可能,請將兩者進行比較,因為-O2和-O3都是C ++開發人員可用的選項。 有時-O2會贏。 有時-O3會贏。 如果兩者都可用,那只是更多信息,可用於通過進行這些速度比較來支持您要完成的任務。

暫無
暫無

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

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