openmp中有一些同步機制可以避免執行緒競爭問題的發生。可以使用同步機制,使得執行緒只有執行到某個語句,才能繼續執行後面的程式。在程式需要訪問可能產生競爭的記憶體資料的時候,都需要插入相應的臨界區**。
乙個例子是定積分確定求圓周率pi的值:
函式介面只需要確定區間0-1之間的分段數,段數越多,pi的值自然越精確。
序列程式非常簡單:
double get_pi(const int& n)
return pi;
}
而使用openmp的並行程式中,求取不同段的段值之間並沒有資料相關性,因此存在潛在的並行性。唯一的問題是如何定義每段的段值變數,是用乙個長度為段數的陣列,還是只用乙個變數定義即可呢?前者的並行思路非常清晰,但是如果段數很多,無疑需要很大的空間;後者當然是我們所追求的,既能加速又能避免不必要的空間開銷。但如果不同執行緒計算段值使用同一變數,如何避免執行緒之間的競爭呢?
很明顯,只要隔離開不同執行緒之間的操作順序即可。通過臨界區,使得在整體求和過程中只有乙個執行緒能夠同時執行求和部分**;或者使用互斥鎖函式或原子操作等,不同的執行緒執行各自的段值私有變數的求和,執行緒之間也是隔離開來。
在openmp中,提供了三種不同的互斥鎖機制用來對一塊記憶體進行保護,它們分別是:
(1) 臨界區(critical)
(2) 原子操作(atomic)
(3) 庫函式來提供同步操作
double get_pi_omp(const int& n)
// #pragma omp critical
//
// }
omp_lock_t mylock;
omp_init_lock(&mylock);
#pragma omp parallel private(x) firstprivate(sum) num_threads(4)
omp_set_lock(&mylock);
pi += sum;
omp_unset_lock(&mylock);
}omp_destroy_lock(&mylock);
//#pragma omp parallel private(x) firstprivate(sum) num_threads(4)
//
// #pragma omp atomic
// pi += sum;
// }
return pi;
}
在main函式中檢測,設定0-1之間的分段數n = 120000000, 檢測**以及結果如圖:
int main(int argc, char** argv)
雙核四執行緒i3 cpu處理器下,開啟四個執行緒,三種互斥鎖的方式效率是極其相近的,
都在0.53s左右,而序列執行為1.08s。
OpenMP 執行緒互斥鎖
openmp是跨平台的多核多執行緒程式設計的一套指導性的編譯處理方案 compiler directive 指導編譯器將 編譯為多執行緒程式。多執行緒程式設計中肯定會涉及到執行緒之間的資源共享問題,就可以使用互斥鎖,就是只有獲得互斥鎖的執行緒可以執行,其他執行緒阻塞。1.openmp中的互斥鎖函式 ...
OpenMP 執行緒互斥鎖
openmp是跨平台的多核多執行緒程式設計的一套指導性的編譯處理方案 compiler directive 指導編譯器將 編譯為多執行緒程式。多執行緒程式設計中肯定會涉及到執行緒之間的資源共享問題,就可以使用互斥鎖,就是只有獲得互斥鎖的執行緒可以執行,其他執行緒阻塞。1.openmp中的互斥鎖函式 ...
python之互斥鎖
from threading import thread,lock import os,time 互斥鎖 def work global n lock.acquire 鎖住n,讓他依次執行 temp n print n time.sleep 0.1 n temp 1 print n lock.rel...