簡體   English   中英

正確使用內部函數和openmp

[英]correct use of interal function and openmp

我有一個for循環,它調用內部函數:

some variables
for(int i=0; i< 10000000; i++)
    func(variables)

基本上,func獲取對某個數組A的引用,並在A [i]中插入值-因此,我可以保證,對func的每次調用實際上都嘗試將值插入A中的其他位置,並且所有其他輸入變量都保留在與for循環之前相同。 所以func是線程安全的。

我可以安全地將代碼更改為

some variables
#pragma omp parallel for
for(int i=0; i< 10000000; i++)
    func(variables)

根據我從openmp教程中了解到的,這還不夠好-因為openmp庫不知道給func提供的變量確實是線程安全的,因此這將產生嘗試執行同步的嘗試,這會使事情變慢,並且我需要將變量聲明為私有等。但是,實際上,在嘗試上述代碼時,它似乎確實可以更快,更並行地工作-這是否符合預期? 我只是想確保我沒有錯過任何東西。

func的聲明:

 func(int i, int client_num, const vector<int>& vec)

首先,OpenMP無法神奇地確定對代碼的依賴性。 您的責任是代碼對並行化是正確的。

為了安全地並行化for循環, func必須不具有循環承載的流依賴性或迭代間依賴性,特別是對於寫后讀取模式。 另外,您必須檢查沒有靜態變量。 (實際上,在這個簡短的答案中寫下安全並行化的條件要復雜得多。)


您對func描述是說func會將變量寫入不同的位置。 如果是這樣,則可以通過將pragma omp parallel for來安全地進行並行pragma omp parallel for ,除非其他計算不依賴於禁止並行化的依賴。

您的func原型: func(int i, int client_num, const vector<int>& vec)

有一個vector ,但是它是一個常量,因此vec不應有任何依賴關系。 從不同線程同時讀取是安全的。

但是,您說的輸出是不同的。 這意味着出了點問題。 不可能說出問題所在。 顯示函數原型永遠無濟於事; 我們需要知道func進行了哪種計算。

盡管如此,診斷的一些步驟是:

  • 檢查代碼中的依賴項。 您不得具有以下所示的依賴關系。 請注意,數組A具有循環傳輸的依賴性,這將阻止並行化:

for (int k = 1; k <N; ++k) A[k] = A[k-1]+1;

  • 檢查func是可重入的還是線程安全的。 通常,靜態和全局變量可能會殺死您的代碼。 如果是這樣,您可以通過私有化解決此問題。 在OpenMP中,您可以在private子句中聲明這些變量。 此外,OpenMP中存在threadprivate編譯指示。

您無需在任何地方更改循環變量i,因此編譯器對其進行並行化沒有問題。 由於僅將i復制到您的函數中,因此無法在外部進行更改。

您唯一需要確保的是,您只能在函數內部寫入位置A [i],並且只能讀取位置A [i]。 否則,您可能會遇到比賽條件。

暫無
暫無

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

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