OpenMP多執行緒應用程式程式設計技術

2021-06-04 17:01:37 字數 2987 閱讀 4040

2.1 迴圈並行化

#pragma omp parallel for [clause[clause…]]

for( index = first ; test_expression ; increment_expr)else

task=-1;

return task;

void task_queue()

int my_task;

#pragma omp parallel private(my_task)

my_task=get_next_task();

while(my_task!=-1){

get_task_done(my_task);

my_task=get_next_task();

上述程式的並行部分不斷從乙個任務佇列中取出相應的任務完成,直到完成任務佇列中的所有任務。

6、根據執行緒號分配任務

由於每乙個執行緒在執行的過程中的執行緒標識號是不同的,可以根據這個執行緒標識號來分配不同的任務,下面的例子程式就演示了如何根據執行緒標識號來完成不同的任務。

程式 6. 14

#pragma omp parallel private(myid)

nthreads=omp_get_num_threads();

myid=omp_get_thread_num();

get_my_work_done(myid,nthreads);

在上述的程式中,首先獲得當前所有執行緒的數目,並且根據執行緒的總數以及相應的執行緒標識號來確定相應的工作,完成任務的並行分配。

7、使用迴圈語句分配任務

迴圈並行化是可以單獨在並行化區域中出現的,每乙個迴圈中的任務就被分配到各個工作執行緒中。

程式 6. 15

#pragma omp parallel

printf("outside loop thread=%d\n",omp_get_thread_num());

#pragma omp for

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

printf("inside loop i=%d thread=%d\n",i,omp_get_thread_num());

程式的執行結果:

outside loop thread=0

outside loop thread=1

inside loop i=2 thread=1

inside loop i=0 thread=0

inside loop i=3 thread=1

inside loop i=1 thread=0

可以看出,在迴圈的外部,程式**被各個執行緒複製執行,而在迴圈的內部,迴圈的所有任務被各個執行緒分別完成。從總體上來說,迴圈執行的次數與序列執行的次數一致。

實際上,在openmp程式設計規範中已經對能夠在不同的執行緒中執行不同的任務有所支援。使用工作分割槽(sections)的方法就能夠達到這一點。

8、工作分割槽編碼(sections)

下面是乙個工作分割槽編碼的例項

程式 6. 16

#pragma omp parallel sections

#pragma omp section

printf("section 1 thread=%d\n",omp_get_thread_num());

#pragma omp section

printf("section 2 thread=%d\n",omp_get_thread_num());

#pragma omp section

printf("sectino 3 thread=%d\n",omp_get_thread_num());

程式執行結果為:

section 1 thread=0

section 2 thread=1

sectino 3 thread=0

可以看到,在使用工作分割槽編碼的時候,各個執行緒自動從各個分割槽中獲得任務執行。並且在執行完乙個分割槽的時候,如果分割槽組裡面還有未完成的工作,則繼續取得任務完成。

2.3 執行緒同步

openmp支援兩種不同型別的執行緒同步機制,一種是互斥鎖的機制,可以用來保護一塊共享的儲存空間,使得每一次訪問這塊共享記憶體空間的執行緒最多乙個,保證了資料的完整性;另外一種同步機制是事件通知機制,這種機制保證了多個執行緒之間的執行順序。

1、互斥鎖機制

在openmp中,提供了三種不同的互斥鎖機制用來對一塊記憶體進行保護,它們分別是臨界區(critical),原子操作(atomic)以及由庫函式來提供同步操作。

2、臨界區

#pragma omp critical [(name)]

block

4、原子操作

#pragma omp atomic

x =expr

或者#pragma omp atomic

x++//or x--, --x, ++x

5、執行時庫函式的互斥鎖支援

6、事件同步機制

事件同步機制與上述的鎖機制不同,鎖機制是為了維護一塊**或者一塊記憶體的一致性,使得所有在其上的操作序列化;而事件同步機制則用來控制**的執行順序,使得某一部分**必須在其它的**執行完畢之後才能執行。

7、隱含的同步屏障(barrier)

8、明確的同步屏障語句

在並行執行的時候,在有些情況下,隱含的同步屏障並不能提供有效的同步措施,程式設計師可以在需要的地方插入明確的同步屏障語句#pragma omp barrier。此時,在並行區域的執行過程中,所有的執行執行緒都會在同步屏障語句上進行同步。

#pragma omp parallel

initialization();

#pragma omp barrier

process();

9、迴圈並行化中的順序語句(ordered)

在某些情況下,我們對於迴圈並行化中的某些處理需要規定執行的順序,典型的情況是在一次迴圈的過程中,一大部分的工作是可以並行執行的,而其餘的工作需要等到前面的工作全部完成之後才能夠執行。在迴圈並行化的過程中,可以使用ordered子句使得順序執行的語句直到前面的迴圈都執行完畢之後再執行。

OpenMP多執行緒應用程式效能分析

影響效能的主要因素 根據前述的amdahl定律,我們應當努力提高並行化 在應用程式中的比率,這是通用的提高效率的方法。1 openmp本身的開銷 openmp獲得應用程式多執行緒並行化的能力不是憑空而來的,而是需要一定的程式庫的支援。在這些執行時的程式庫對程式並行加速的同時需要執行庫的本身,因此,庫...

建立多執行緒應用程式

定義命名空間在.net中,多執行緒功能是在system.threading命名空間中定義的。usingsystem.threading 啟動執行緒system.threading命名空間中的thread類代表乙個執行緒物件,用這個類物件可以建立新的執行緒,刪除 暫停和恢復執行緒。下面的 使用thre...

建立多執行緒應用程式

定義命名空間 在.中,多執行緒功能是在system.threading命名空間中定義的。usingsystem.threading 啟動執行緒 system.threading命名空間中的thread類代表乙個執行緒物件,用這個類物件可以建立新的執行緒,刪除 暫停和恢復執行緒。下面的 使用threa...