openmp開啟後計算結果錯誤原因

2021-08-16 14:07:51 字數 1716 閱讀 5758

openmp多執行緒使用方法十分簡單,一般對於for迴圈只需要加一句#pragma omp parallel for就可以了。

新手使用的時候有時候可能會出現開啟omp之後,得到的計算結果是錯的,而且多次執行結果還不相同。

1.   其中乙個可能的原因是你的**中不同的執行緒同時使用某一記憶體的值並且試圖改變它,比如累加操作,這種情況下執行緒x獲取的資料可能不是最新的。

示例1:

參考

#include int main()

; #pragma omp parallel for

for (int i=0;i<10;i++)

sum = sum + a[i];

std::cout<<"sum: "<

如果我們注釋掉#pragma omp parallel for,讓程式先按照傳統序列的方式執行,很明顯,sum = 55。但按照並行方式執行後,sum則會變成其他值,比如在某次執行過程中,sum = 49。其原因是,當某執行緒a執行sum = sum + a[i]的同時,另一線程b正好在更新sum,而此時a還在用舊的sum做累加,於是出現了錯誤。

解決方案:

#include int main();

#pragma omp parallel for reduction(+:sum)

for (int i=0;i<10;i++)

sum = sum + a[i];

std::cout<<"sum: "<

上面**裡,我們在#pragma omp parallel for 後面加上了 reduction(+:sum),它的意思是告訴編譯器:下面的for迴圈你要分成多個執行緒跑,但每個執行緒都要儲存變數sum的拷貝,迴圈結束後,所有執行緒把自己的sum累加起來作為最後的輸出。

reduction雖然很方便,但它只支援一些基本操作,比如+,-,*,&,|,&&,||等。

示例2

int point[8];

float dist[2];

#pragma omp parallel for

for (int i = 0; i < org_feat_len; i++)

由於point宣告在for外部,多個執行緒共同對其操作的時候可能會出現執行緒0執行到dist計算的時候,point已經被其他執行緒給修改了,因此會造成dist計算結果不對。dist宣告在外部,在計算orgfeat的時候存在同樣的問題。因此應該修正為以下:

#pragma omp parallel for

for (int i = 0; i < org_feat_len; i++)

這樣就沒有問題了。

2.  還有個可能的問題參考

你寫成這樣了

#pragma omp for

for(i = 0, i < n;i++)

這樣的寫法是錯誤的,在openmp for語句中一定要宣告好這個變數的作用域,上述的寫法i是公用變數,也就是說pragma omp for確實是分配給

多個執行緒等量的任務,然而由於每個執行緒都對i進行i++的這個操作,有些i的變數就被跳過了,

正確的寫法應該是:

#pragma omp for

for(int i = 0, i < n;i++)

vue計算結果

id 中的內容可以是data中的資料,也可以是表示式 for 工資 type text placeholder 請輸入您的工資 v model salary 您的個人所得稅為 中可以繫結表示式,所以就繫結元件中的方法呼叫,得到的是方法的返回值 type text v model src vue.js...

mysql對結果計算 MYSQL計算結果

我正在 mysql 5.0中構建乙個查詢來計算學生的學期成績.初始表 studentitemgrades 包含將用於計算最終成績的作業列表等.每項作業都有乙個possiblescore,grade和weight.計算應對所有類似加權的專案進行分組,並根據分配到期的日期範圍提供sum grade su...

中綴轉字尾,計算結果

import queue 判斷符號優先符 defcompareii a,b if a or a and b or b return 0elif a or b return 0return 1 中綴變字尾 1 乙個數字棧 2 乙個符號棧 3 判斷符號的優先順序 4 數字棧跳到符號棧 5 輸出符號棧 d...