成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

多核中的并行前綴和計算

開發 前端
前綴和計算在并行計算中很有用,因為在處理負載平衡問題時,經常需要將若干段數據重新平分,計算前綴和通常是一種有效的將數據平分的方法。例如在并行基數排序中,就會用到了前綴和的計算。而下面先看看單線程環境中的串行前綴和計算。

前綴和計算在并行計算中很有用,因為在處理負載平衡問題時,經常需要將若干段數據重新平分,計算前綴和通常是一種有效的將數據平分的方法。例如在并行基數排序中,就會用到了前綴和的計算。而下面先看看單線程環境中的串行前綴和計算。

1、串行前綴和的計算

如果給定一個數列a[n],令S[k] = a[0]+a[1]+...+a[k],(k = 0, 1, 2…n-1),數列S[k]即為數列a[n]的前綴和。例如下面一列數據:

a[4] = {1,   2,   3,   4};

其前綴和為

S[0] = a[0] = 1;

S[1] = a[0] + a[1] = 1+ 2 = 3;

S[2] = a[0] + a[1] + a[2] = 1 + 2 + 3 = 6;

S[3] = a[0] + a[1] + a[2] + a[3] = 1 + 2 + 3 + 4 = 10;

前綴和的計算非常簡單,一般地,可以用下面的函數來進行串行前綴和的計算:

  1. /**   串行前綴和計算函數 
  2.  
  3.   
  4.  
  5.        @param  T * pInput - 輸入數據  
  6.  
  7.        @param  T *pOutput - 輸出數據(前綴和)    
  8.  
  9.        @param  int nLen - 輸入數據長度      
  10.  
  11.        @return  void - 無 
  12.  
  13. */ 
  14.  
  15. template <class T> 
  16.  
  17. void Sequential_PrefixSum(T * pInput, T *pOutput, int nLen) 
  18.  
  19.  
  20.     int i; 
  21.  
  22.   
  23.  
  24.     pOutput[0] = pInput[0]; 
  25.  
  26.     for ( i = 1; i < nLen; i++ ) 
  27.  
  28.     { 
  29.  
  30.         pOutput[i] = pInput[i] + pOutput[i-1]; 
  31.  
  32.     } 
  33.  

在上面的串行前綴和計算代碼中可以看出,每次循環都依賴于上一次循環的結果,因此無法直接對循環進行并行化,要進行并行化則必須修改計算方法,下面就來看如何進行并行前綴和的計算。

2、并行前綴和的計算

前綴和的并行計算方法有許多種,David Callahan的論文“Recognizing and Parallelizing Bounded Recurrences”中給出了一種適合共享存儲多處理器系統中的有界遞歸計算的通用方法,前綴和計算屬于有界遞歸計算的一個特例。下面先以一個實例來講解整個并行計算的過程:

例:假設有4個處理器要計算16個整數的前綴和,這16個整數如下:

1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16

1步,先將上面數據平分成4組,每個處理器各計算一組數據的前綴和,如下所示:

1   2   3   4 5   6   7   8 9   10   11   12 13   14   15   16

1   3   6   10 5   11   18   26 9   19   30   42 13   27   42   58

2步,選取每組數據的***一個數據,對這幾個數據計算前綴和,如下所示:

1  3  6   10 5   11   18   26 9   19   30   42 13   27   42  58

1  3  6   10 5   11   18   36 9   19   30   78 13   27   42  136

經過這步的計算后,可以很容易發現,每組的***一個數據的值已經變成了原始數據在它所處位置之前(包含本位置)的所有數據的和。例如:

36 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8

78 = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12

3步:從第2組數開始,將每組中的數(除***一個數外)加上它的前一組數的***一個數,即可得到所有數的前綴和。如下所示:

 (1 3 6 10) (5+10 11+10 18+10 36) (9+36 19+36 30+36 78)  (13+78 27+78 42+78 136

(1  3  6  10)  (15  21  28  36)  (45  55  66  78)  (91  105  120  136

從上面的計算過程可以看出,第1步和第3步都是很容易進行并行化計算,第2步中,由于計算量非常小,用串行計算即可,下面給出上面處理過程的代碼實現:

 

  1. #define  MIN_PRARLLEL_PREFIXSUM_COUNT    8192 
  2.  
  3.   
  4.  
  5. /**   并行前綴和計算函數 
  6.  
  7.   
  8.  
  9.        @param  T * pInput - 輸入數據  
  10.  
  11.        @param  T *pOutput - 輸出數據(前綴和)    
  12.  
  13.        @param  int nLen - 輸入數據長度      
  14.  
  15.        @return  void - 無 
  16.  
  17. */ 
  18.  
  19. template<class T> 
  20.  
  21. void Parallel_PrefixSum(T * pInput, T *pOutput, int nLen) 
  22.  
  23.  
  24.     int i; 
  25.  
  26.   
  27.  
  28.     int nCore = omp_get_num_procs(); 
  29.  
  30.   
  31.  
  32.        if ( nCore < 4 || nLen < MIN_PRARLLEL_PREFIXSUM_COUNT ) 
  33.  
  34.     { 
  35.  
  36.         Sequential_PrefixSum(pInput, pOutput, nLen); 
  37.  
  38.         return; 
  39.  
  40.     } 
  41.  
  42.   
  43.  
  44.        int nStep = nLen / nCore; 
  45.  
  46.     if ( nStep * nCore < nLen ) 
  47.  
  48.     { 
  49.  
  50.         nStep += 1; 
  51.  
  52.     } 
  53.  
  54.   
  55.  
  56. #pragma omp parallel for num_threads(nCore) 
  57.  
  58.     for ( i = 0; i < nCore; i++ ) 
  59.  
  60.     { 
  61.  
  62.         int k; 
  63.  
  64.         int nStart = i * nStep; 
  65.  
  66.         int nEnd = (i+1) * nStep; 
  67.  
  68.         if ( nEnd > nLen ) 
  69.  
  70.         { 
  71.  
  72.             nEnd = nLen
  73.  
  74.         } 
  75.  
  76.         pOutput[nStart] = pInput[nStart]; 
  77.  
  78.         for ( k = nStart+1; k < nEnd; k++ ) 
  79.  
  80.         { 
  81.  
  82.             pOutput[k] = pInput[k] + pOutput[k-1]; 
  83.  
  84.         } 
  85.  
  86.     } 
  87.  
  88.   
  89.  
  90.     for ( i = 2; i < nCore; i++ ) 
  91.  
  92.     { 
  93.  
  94.         pOutput[i * nStep - 1] += pOutput[(i-1) * nStep - 1]; 
  95.  
  96.     } 
  97.  
  98.   
  99.  
  100.     pOutput[nLen-1] += pOutput[(nCore-1)*nStep - 1]; 
  101.  
  102.   
  103.  
  104. #pragma omp parallel for num_threads(nCore-1) 
  105.  
  106.     for ( i = 1; i < nCore; i++ ) 
  107.  
  108.     { 
  109.  
  110.         int k; 
  111.  
  112.         int nStart = i * nStep; 
  113.  
  114.         int nEnd = (i+1) * nStep - 1; 
  115.  
  116.         if ( nEnd >= nLen ) 
  117.  
  118.         { 
  119.  
  120.             nEnd = nLen - 1; 
  121.  
  122.         } 
  123.  
  124.         for ( k = nStart; k < nEnd; k++ ) 
  125.  
  126.         { 
  127.  
  128.             pOutput[k] += pOutput[nStart-1]; 
  129.  
  130.         } 
  131.  
  132.     } 
  133.  
  134.     return; 
  135.  

從上面并行前綴和的計算過程可以看出,它的計算量比串行前綴和的計算增加了差不多一倍,如果考慮程序中的實際開銷,計算增加量還不止一倍。因此在雙核CPU機器上,使用并行前綴和計算沒有任何意義,只有在超過4CPU機器上,它才有實用價值。

Parallel_PrefixSum()函數中,先是判斷CPU核數是否小于4,并且判斷了計算量是否不足,如果兩個判斷條件中有任何一個滿足,則調用串行前綴核計算函數進行計算,然后才進行并行前綴和的計算。在并行計算時只是簡單地將計算平攤到各個CPU上,沒有考慮CPU核數較多情況下計算量平攤到各個CPU核上,線程粒度過小的問題,主要是為了不使代碼看起來過于繁瑣。如有需要可以修改成自動計算出最合適的線程數量(可能小于CPU核數),然后并行計算時使用相應的線程數量即可。

原文鏈接:http://blog.csdn.net/drzhouweiming/article/details/3164974

責任編輯:陳四芳 來源: blog.csdn.net
相關推薦

2011-03-24 09:23:43

.NET 4多核并行

2010-06-10 08:37:04

并行計算

2009-06-03 15:27:07

CPU網絡優化網康

2010-03-22 14:45:40

云計算

2018-06-14 09:38:53

Linux多核編程

2024-04-01 13:09:41

MySQL數據庫

2011-08-05 16:41:48

iOS 隊列 內存

2010-03-19 17:23:45

云計算

2010-03-02 09:10:41

Visual Stud

2010-03-08 09:17:13

F#異步

2023-11-07 12:00:41

數據并行Java 8數據

2010-11-29 08:57:20

Visual Stud.NET 4

2011-08-22 11:07:16

IOS 開發多核內存

2013-12-16 15:04:51

多核編程

2009-03-31 19:31:09

多核計算Sun

2009-09-01 09:06:08

并行編程

2009-07-30 10:59:44

Scala和Erlan多核

2014-04-24 10:25:15

2013-12-18 16:32:27

多核編程同步模式

2010-03-11 15:23:44

Visual Stud
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99热精品国产 | 99tv| 亚洲国产69| 夜夜骑av| 精品蜜桃一区二区三区 | 日韩一区二区免费视频 | 亚洲天堂av一区 | 国产丝袜一区二区三区免费视频 | 亚洲精品福利在线 | 久久久日韩精品一区二区三区 | 欧美福利精品 | 国产亚洲精品综合一区 | 中文字幕不卡在线88 | 国产精品久久久久久久久久久免费看 | 蜜臀久久99精品久久久久久宅男 | 欧美精产国品一二三区 | 黄色一级毛片免费看 | wwwxx在线观看 | 91麻豆精品国产91久久久久久久久 | 亚洲精品一区二区在线观看 | 国产一区二区三区免费 | 亚洲综合色站 | 国产区在线免费观看 | 91久久久久久久久 | 美女一级a毛片免费观看97 | 国产成人综合亚洲欧美94在线 | 欧美日韩亚洲一区二区 | 91麻豆精品国产91久久久资源速度 | 精品国产乱码久久久久久蜜柚 | 国产成人自拍av | 久产久精国产品 | 国产精品一区二区福利视频 | 国产精品免费一区二区三区四区 | 亚洲永久精品国产 | 精品一区二区三区在线播放 | 成人午夜在线 | 狠狠操av| 最新av在线播放 | 亚洲不卡在线观看 | 天天综合网91| 久久精品色欧美aⅴ一区二区 |