簡體   English   中英

GCC OpenMP並行處理比Visual Studio減少速度更慢

[英]GCC OpenMP parallel for reduction MUCH slower than Visual Studio

我和我的一個朋友遇到了有關parallel for reduction GCC的性能問題。

編碼:

#include <cstdio>

int main() {
    int tans = 0;
    for (int i = 0; i < 100000; ++i)
        #pragma omp parallel for reduction(+:tans)
        for (int id = 0; id < 10000; ++id) {
            tans++;
        }
    printf("%d\n", tans);
}

(此無用的代碼僅用於演示問題)

當使用GCC(版本4.9.2(tdm64-1))進行編譯並在我的4核8線程系統(Win 8.1 64b)上運行時,代碼運行大約5s,而使用num_threads(1)僅運行0.5s。

我還在24核系統(gcc版本4.8.2(Ubuntu 4.8.2-19ubuntu1))上嘗試了相同的代碼,並行版本仍然非常慢,運行時間非常不穩定,范圍從1s到10s 。

使用Visual Studio 2013,代碼總是幾乎立即完成。 生成的匯編代碼可以在這里找到: https : //gist.github.com/ftfish/f8ffdb9106b82ae63925

我做錯了什么? 是因為parallel for reduction的開銷嗎? 為什么Visual Studio的性能更好? 先感謝您。

如果您的實際代碼與此代碼一樣簡單,則很可能會損失很多編譯器優化的機會。 g++ -O3為您發布的減去OMP行的代碼生成以下匯編:

.cfi_startproc
subq    $8, %rsp
.cfi_def_cfa_offset 16
movl    $1000000000, %esi
movl    $.LC0, %edi
xorl    %eax, %eax
call    printf
xorl    %eax, %eax
addq    $8, %rsp
.cfi_def_cfa_offset 8
ret

正如你看到的,絕對沒有什么在這里是在運行時計算,其循環完全優化掉。 這樣,程序立即完成。 如果讓計算在運行時進行,顯然會增加它。 在這里,您可以看到添加OMP行實際上使計算在運行時發生,生成的程序集太長而無法粘貼到此處。

編輯:

我用g ++和clang ++都測試了OMP代碼,並且可以重現您的問題(g ++大約0.3s,clang ++ 0.006s,即即時)。 clang確實優化了兩個循環,即使使用OMP線也是如此。 由於您的代碼非常完美,因此這是gcc優化器的錯誤。 現在還不清楚gcc伙計們是否搞砸了,或者是否遵循了諸如“如果用戶編寫OMP,他應該通過測量並行版本更快來發現它。不要對其進行優化”之類的道理。 我會把錢花在后者上,但如果要確定的話,請訪問gcc bugzilla。

剩下的就是我在評論中提到的結論: 衡量一切。

在這種特殊情況下:如果要定位gcc和VC,只需在兩種環境中同時測量兩種變體,然后將更好的一種寄給客戶。 如果您認為這是gcc性能錯誤,則仍可以為他們編寫錯誤報告。

最后一句話:

如果您的實際代碼是像這樣的雙循環,請考慮並行處理最外面的代碼,以節省昂貴的OMP啟動過程(但是measure(!),這當然可能無濟於事。)

暫無
暫無

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

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