氣泡排序
for
(list_length=n;list_length>=
2;list_length--)}
}
這裡陣列a儲存n個int型整數,演算法將他們公升序排列。外部迴圈先找到列表最大元素將他存在a[n-1]中,然後尋找次大的元素並存在a[n-2]中,以此類推。因此,第一遍處理全部的n個元素,第二遍處理除了最大元素外的所有元素,它處理乙個n-1個元素的列表,以此類推。
內迴圈比較當前列表中的連續元素對。當發現一對是無序的時候,就交換他們。
顯然,在外部迴圈中有乙個迴圈依賴,在外部迴圈中的任何一次迭代中,當前列表的內容依賴於外部迴圈的前一次迭代。內部迴圈的迴圈依賴也容易發現。在第i次迭代中,被比較的元素依賴於第i-1次迭代。我們完全不清楚怎樣在不完全重寫演算法的情況下移除任何乙個迴圈依賴。
奇偶交換排序
for
(phase=
0;phase)else
for(i=
1;i1;i+=2
)}
列表儲存n個整數,演算法對他們進行公升序排列。在乙個偶階段phase%20裡,每個偶下標元素a[i]與它左邊的元素a[i-1]相比較。如果他們是沒有排好序的,就交換他們。在乙個奇階段phase%21裡,每個奇下標元素與它右邊的元素相比較。如果他們是沒有排好序的,就交換。
不難發現外部迴圈有迴圈依賴。例如a=9,7,8,6。在階段0中,內部迴圈將比較9和7,8和6,得到7,9,6,8.在階段1中,將比較9和6.然而,如果階段0和1同時進行,階段1比較的就是7和8,因此直接並行外部for不好。但是內部for迴圈並沒有任何迴圈依賴。
奇偶排序的第乙個openmp實現
for
(phase=
0;phaseelse
#pragma omp parallel for num_threads(thread_count)\
default(none) shared(a,n) private(i,tmp)
for(i=
1;i1;i+=2
)}}
首先會有潛在的問題產生。
首先,儘管任何乙個偶階段迭代並不依賴任何這個階段的其它迭代,但是還需要注意,對p階段和p+1階段卻不是這樣。我們需要確定在任何乙個執行緒開始p+1階段之前,所有的執行緒必須先完成p階段。然而,像parallel指令那樣,parallel for指令在迴圈結束處有乙個隱式路障,因此,在所有的執行緒完成當前階段(階段p)之前,沒有執行緒可以進入下乙個階段。
其次,是建立和合併執行緒的開銷。openmp實現可能會在每一遍外部迴圈都建立和合併thread_count個執行緒。
奇偶排序的第二個openmp實現
#pragma omp parallel num_threads(threads_count)\
default(none) shared(a,n) private(i,tmp,phase)
for(phase=
0;phase}else}}
}
每次執行內部迴圈時,使用同樣數量的執行緒。因此只建立一次執行緒,並在每次內部迴圈的執行中重用他們,這樣做可能更好。
用parallel指令在外部迴圈前建立thread_count個執行緒的集合。然後,我們不在每次內部迴圈執行時,建立一組新的執行緒,而是使用乙個for指令,告訴openmp用已有的執行緒組來並行化for迴圈。
與parallel for指令不同的是for指令不建立任何執行緒。它使用已經在parallel塊中建立的執行緒。在迴圈的末尾有乙個隱式的路障。
《並行程式設計導論》02 openmp
global result 0.0 pragma omp parallel num threads thread count openmp提供了乙個更清晰的方法來避免local trap的序列執行 將global result定義為乙個歸約變數。歸約操作符是乙個二元操作,規約就是將相同的歸約操作符重...
《並行程式設計導論》04openmp
parallel for指令中,將各次迴圈分配給執行緒的操作是由系統完成的。然而,大部分openmp實現只是粗略地使用塊分割。乙個更好的分配方案是輪流分配執行緒的工作 迴圈劃分 在迴圈劃分中,歌詞迭代 流地一次乙個地分配給執行緒。不難發現,乙個好的迭代分配能夠對效能有很大的影響。在openmp中,將...
OpenMP並行程式設計(一)
openmp並行程式設計 一 openmp是乙個支援共享儲存並行設計的庫,特別適宜多核cpu上的並行程式設計。今天在雙核cpu機器上試了一下openmp並行程式設計,發現效率方面超出想象,因此寫出來分享給大家。在vc8.0中專案的屬性對話方塊中,左邊框裡的 配置屬性 下的 c c 下的 語言 頁裡,...