[英]Performance of matrix multiplications remains unchanged with OpenMP in C++
auto t1 = chrono::steady_clock::now();
#pragma omp parallel
{
for(int i=0;i<n;i++)
{
#pragma omp for collapse(2)
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
{
C[i][j]+=A[i][k]*B[k][j];
}
}
}
}
auto t2 = chrono::steady_clock::now();
auto t = std::chrono::duration_cast<chrono::microseconds>( t2 - t1 ).count();
有和沒有並行化,變量t保持相當恆定。 我不確定為什么會這樣。 同樣,有時t輸出為0。我面臨的另一個問題是,如果我將n的值增加到500,那么編譯器將無法運行該程序。(這里我取n = 100)我我在GNU GCC編譯器中使用code :: blocks。
提議的OpenMP並行化是不正確的,並且可能導致錯誤的結果。 當指定collapse(2)
,線程“同時”執行(j,k)迭代。 如果兩個(或更多)線程在相同的j上但不同的k上工作,則它們將A[i][k]*B[k][j]
的結果累加到相同的數組位置C[i][j]
。 這就是所謂的競爭條件,即“兩個或多個線程可以訪問共享數據,並且它們試圖同時更改共享數據”( 什么是競爭條件? )。 盡管代碼對OpenMP無效,但數據爭用並不一定會導致錯誤的結果,並且可能會根據多個因素(調度,編譯器實現,線程數等)產生錯誤的結果。 為了解決上面代碼中的問題,OpenMP提供了reduction
條款:
#pragma omp parallel
{
for(int i=0;i<n;i++) {
#pragma omp for collapse(2) reduction(+:C)
for(int j=0;j<n;j++) {
for(int k=0;k<n;k++) {
C[i][j]+=A[i][k]*B[k][j];
因此,“將在每個隱式任務(...)中創建一個私有副本,並使用reducer-identifier的初始化值對其進行初始化。在該區域結束之后,原始列表項將使用私有副本的值進行更新。使用與歸約標識符關聯的組合器”( http://www.openmp.org/wp-content/uploads/openmp-4.5.pdf )。 請注意,自OpenMP 4.5起,該標准直接支持C語言中數組的縮減(請檢查編譯器是否支持它,否則,有一些舊的手動方法可以實現,即OpenMp中的數組縮減 )。
但是,對於給定的代碼,應該避免最內層循環的並行化可能更合適,這樣根本就不需要減少操作:
#pragma omp parallel
{
#pragma omp for collapse(2)
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
for(int k=0;k<n;k++) {
C[i][j]+=A[i][k]*B[k][j];
對於較小的矩陣和/或少量的線程,串行可以比OpenMP版本更快。 在使用最多16個內核,n = 1000的Intel機器上,當激活-O3優化時,GNU編譯器v6.1的收支平衡約為4個內核,而使用-O0編譯的收支平衡約為2個內核。 為了清楚起見,我報告了我測量的性能:
Serial 418020
----------- WRONG ORIG -- +REDUCTION -- OUTER.COLLAPSE -- OUTER.NOCOLLAPSE -
OpenMP-1 1924950 2841993 1450686 1455989
OpenMP-2 988743 2446098 747333 745830
OpenMP-4 515266 3182262 396524 387671
OpenMP-8 280285 5510023 219506 211913
OpenMP-16 2227567 10807828 150277 123368
減少使用會導致性能損失(加速倒退)。 外部並行化(不折疊或不折疊)是最佳選擇。
關於大型矩陣的故障,可能的原因與可用堆棧的大小有關。 嘗試同時擴大系統和OpenMP堆棧的大小,即
ulimit -s unlimited
export OMP_STACKSIZE=10000000
collapse
指令實際上可能對此負責,因為索引j
是使用divide / mod操作重新創建的。
您嘗試沒有collapse
嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.