[英]OpenMP - Nested for-loop becomes faster when having parallel before outer loop. Why?
[英]Why is this for loop not faster using OpenMP?
我從一個更大的2D程序中提取了這個簡單的成員函數,它所做的只是一個for循環訪問三個不同的數組並進行數學運算(1D卷積)。 我一直在測試使用OpenMP來加快這個特定的功能:
void Image::convolve_lines()
{
const int *ptr0 = tmp_bufs[0];
const int *ptr1 = tmp_bufs[1];
const int *ptr2 = tmp_bufs[2];
const int width = Width;
#pragma omp parallel for
for ( int x = 0; x < width; ++x )
{
const int sum = 0
+ 1 * ptr0[x]
+ 2 * ptr1[x]
+ 1 * ptr2[x];
output[x] = sum;
}
}
如果我在debian / wheezy amd64上使用gcc 4.7,整個程序在8 CPU機器上執行速度要慢很多。 如果我在debian / jessie amd64上使用gcc 4.9(在這台機器上只有4個CPU),整個程序執行的差別很小。
使用time
進行比較:單核運行:
$ ./test black.pgm out.pgm 94.28s user 6.20s system 84% cpu 1:58.56 total
多核運行:
$ ./test black.pgm out.pgm 400.49s user 6.73s system 344% cpu 1:58.31 total
哪里:
$ head -3 black.pgm
P5
65536 65536
255
因此在執行期間Width
設置為65536
。
如果那樣,我使用cmake進行編譯:
add_executable(test test.cxx)
set_target_properties(test PROPERTIES COMPILE_FLAGS "-fopenmp" LINK_FLAGS "-fopenmp")
並且CMAKE_BUILD_TYPE設置為:
CMAKE_BUILD_TYPE:STRING=Release
這意味着-O3 -DNDEBUG
我的問題是,為什么這個for
循環使用多核不會更快? 陣列上沒有重疊,openmp應該平均分割內存。 我不知道瓶頸來自哪里?
編輯:因為它被評論,我將我的輸入文件更改為:
$ head -3 black2.pgm
P5
33554432 128
255
因此在執行期間Width
現在設置為33554432
(應該考慮足夠)。 現在時間顯示:
單核運行:
$ ./test ./black2.pgm out.pgm 100.55s user 5.77s system 83% cpu 2:06.86 total
多核運行(由於某種原因,cpu%總是低於100%,這表明根本沒有線程):
$ ./test ./black2.pgm out.pgm 117.94s user 7.94s system 98% cpu 2:07.63 total
我有一些一般性評論:
1.在優化代碼之前,請確保數據是16字節對齊的。 這對於想要應用的優化非常重要。 如果數據被分成3個部分,最好添加一些虛擬元素,使3個部分的起始地址全部為16字節對齊。 通過這樣做,CPU可以輕松地將數據加載到緩存行中。
2.在實現openMP之前,確保簡單函數已向量化 。 大多數情況下,使用AVX / SSE指令集應該可以為您提供2到8倍的單線程改進。 對於您的情況非常簡單:創建一個恆定的mm256寄存器並將其設置為值2,並將8個整數加載到3個mm256寄存器。 使用Haswell處理器,可以一起完成一次加法和一次乘法。 所以理論上,如果AVX管道可以填充,循環應該加速12倍!
3.有時並行化會降低性能 :現代CPU需要數百到數千個時鍾周期才能預熱,進入高性能狀態並擴展頻率。 如果任務不夠大,很可能在CPU預熱之前完成任務,並且無法通過並行獲得速度提升。 並且不要忘記openMP也有開銷:線程創建,同步和刪除。 另一種情況是內存管理不善。 數據訪問非常分散,所有CPU內核都處於空閑狀態並等待來自RAM的數據。
我的建議:
您可能想嘗試英特爾MKL,不要重新發明輪子。 該庫經過極端優化,沒有浪費時鍾周期。 可以與串行庫或並行版本鏈接,如果可以並行,則可以保證速度提升。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.