[英]Shared vectors in OpenMP
我試圖平行我正在使用的程序並得到以下問題。 如果多個線程需要在同一個向量上讀取/寫入但向量的不同元素,我會失去性能嗎? 我感覺這就是我的程序在平行化時幾乎沒有得到更快的原因。 請使用以下代碼:
#include <vector>
int main(){
vector<double> numbers;
vector<double> results(10);
double x;
//write 10 values in vector numbers
for (int i =0; i<10; i++){
numbers.push_back(cos(i));
}
#pragma omp parallel for \
private(x) \
shared(numbers, results)
for(int j = 0; j < 10; j++){
x = 2 * numbers[j] + 5;
#pragma omp critical // do I need this ?
{
results[j] = x;
}
}
return 0;
}
顯然,實際的程序執行的操作要昂貴得多,但這個例子只能解釋我的問題。 那么for循環可以快速完全並行完成,還是不同的線程必須等待彼此,因為一次只有一個線程可以訪問矢量號,盡管它們都是讀取矢量的不同元素?
與寫操作相同的問題:我是否需要關鍵編譯指示或者沒有問題,因為每個線程寫入向量結果的不同元素? 我很滿意我能得到的每一個幫助,也很高興知道是否有更好的方法來做到這一點(可能根本不使用矢量,但簡單的數組和指針等?)我也讀過矢量不是在某些情況下線程安全,建議使用指針: OpenMP和STL向量
非常感謝你的幫助!
我想大多數線程中的向量問題都是如果它必須調整大小,然后它將向量的全部內容復制到內存中的新位置(一個更大的已分配塊),如果你並行訪問它然后你只是試圖讀取一個已被刪除的對象。
如果你沒有調整數組的大小,那么我從來沒有遇到過對向量的並發讀寫的任何麻煩(顯然,只要我沒有寫兩次相同的元素)
至於缺乏性能提升,openmp臨界區將使程序速度降低到可能與僅使用1個線程相同(取決於在關鍵部分之外實際完成的程度)
您可以刪除關鍵部分聲明(考慮上述條件)。
你沒有得到加速,正是因為關鍵的sectino,這是多余的,因為相同的元素永遠不會同時被修改。 刪除關鍵部分,它會工作得很好。
您也可以使用調度策略,因為如果內存訪問不是線性的(在您給出的示例中),則線程可能會爭用緩存(在同一緩存行中編寫元素)。 OTOH如果在你的情況下給出元素的數量並且循環中沒有分支(因此它們將以大約相同的速度執行), static
,默認的IIRC,應該最好地工作。
(順便說一句,你可以在循環中聲明x
以避免private(x)
,並且shared
指令暗示IIRC(我從未使用它)。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.