[英]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.