小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

多核開發(fā)入門指南

 軟件團(tuán)隊頭目 2008-11-23

一、為什么需要多核開發(fā)?

        答案很簡單,目前的芯片制造技術(shù)對CPU主頻的提升已經(jīng)達(dá)到一個極限了,也就是說性能的垂直伸縮已經(jīng)不太可能了。因此通過多核的方法,可以讓程序橫向的伸縮,這就類似于用多臺服務(wù)器實(shí)現(xiàn)負(fù)載均衡(水平伸縮),而不是簡單的靠將服務(wù)器升級成小型機(jī)來提供處理能力(垂直伸縮)。

        雖然多核并行計算的概念已經(jīng)存在了幾十年了,但直到最近多核CPU在PC上的普及,多核開發(fā)才不得不提引起程序員的重視。

        多核開發(fā)的本質(zhì)就是使用多線程進(jìn)行程序開發(fā),我們在學(xué)數(shù)據(jù)結(jié)構(gòu)和算法的時候,寫的所有的算法都是面向單線程的。而多核開發(fā)的目的就是將這些算法改造成多線程的支持,然后系統(tǒng)運(yùn)行時將這些多線程平均分配到多核處理器上,以實(shí)現(xiàn)運(yùn)行的加速。

 

二、如何進(jìn)行多核開發(fā)

      如果你很熟悉POSIX threads (pthreads) 或者 WinAPI threads,你就可以自己進(jìn)行開發(fā)。
      如果你不想設(shè)計過多底層的線程操作,那就選擇一個并發(fā)開發(fā)平臺,由平臺來自動協(xié)調(diào),調(diào)度和管理多核資源。并發(fā)開發(fā)平臺包括各種線程池的庫,例如
          .NET的ThreadPool類
          Java的Concurrent類
          消息傳遞環(huán)境,例如MPI
          data-parallel編程環(huán)境,例如NESL, RapidMind, ZPL
          task-parallel編程環(huán)境, 例如Intel的Threading Building Blocks (TBB) 和 Microsoft的Task Parallel Library (TPL)
          動態(tài)編程環(huán)境,例如Cilk or Cilk++或者業(yè)界標(biāo)準(zhǔn)OpenMP. 
    這些并發(fā)平臺通過提供語言抽象,擴(kuò)充注釋或者提供庫函數(shù)的方式來支持多核開發(fā)。

 

三、使用并發(fā)開發(fā)平臺具體有哪些好處

      我們從下面幾個方面來看:

      軟件開發(fā)中最重要的三個考慮的要素就是
              程序的性能 (使用多核就是為了提升程序的性能的)
              開發(fā)的時間
              程序的可靠性

      而其中影響開發(fā)時間的三個要素是

                 伸縮性:如果你自己編寫線程,你必須考慮用戶是雙核,四核還是八核。如何將線程自動適應(yīng)用戶的核數(shù),并且在多核上將線程均衡的負(fù)載。
                 代碼簡潔:直接使用底層線程庫操作代碼是十分復(fù)雜的
                 模塊化:直接使用底層線程庫操作還會破壞代碼的模塊化

 

四、具體實(shí)例

          下面以Fibonacci的例子來演示:它的遞歸算法經(jīng)常被用來作為多核開發(fā)的例子。


          單核時代,我們寫Fibonacci代碼的方法如下:

  1. int fib(int n) 
  2. {
  3.   if (n < 2) return n;
  4.  else {
  5.       int x = fib(n-1);
  6.       int y = fib(n-2);
  7.       return x + y;
  8.      }
  9. }       
  10.                 
  11. int main(int argc, char *argv[])
  12. {       
  13.   int n = atoi(argv[1]);
  14.  int result = fib(n);
  15.  printf("Fibonacci of %d is %d.\n", n, result);
  16.  return 0;
  17. }

       這個算法的核心就是f(n) = f(n-1) + f(n-2),當(dāng)n很大時,我們希望計算f(n-1)和f(n-2)這兩個任務(wù)能否分?jǐn)傇谝粋€雙核處理器上同時執(zhí)行。

 

       如果直接使用WinAPI-threaded操作的代碼如下:


  

  1.       int fib(int n)
  2.  {
  3.    if (n < 2) return n;
  4.    else {
  5.     int x = fib(n-1);
  6.     int y = fib(n-2);
  7.      return x + y;
  8.      }
  9.  }
  10.      
  11.  typedef struct {
  12.        int input;
  13.        int output;
  14.      } thread_args;
  15.      
  16.   void *thread_func ( void *ptr )
  17.   {
  18.     int i = ((thread_args *) ptr)->input;
  19.     ((thread_args *) ptr)->output = fib(i);
  20.     return NULL;
  21.   }
  22.       
  23.  int main(int argc, char *argv[])
  24.      {
  25.        pthread_t thread;
  26.        thread_args args;
  27.        int status;
  28.        int result;
  29.        int thread_result;
  30.        if (argc < 2) return 1;
  31.        int n = atoi(argv[1]);
  32.        if (n < 30) result = fib(n);
  33.        else {
  34.          args.input = n-1;
  35.          status = pthread_create(thread,
  36.      NULL, thread_func,
  37.      (void*) &args );
  38.         // main can continue executing while the thread executes.
  39.          result = fib(n-2);
  40.         // Wait for the thread to terminate.
  41.          pthread_join(thread, NULL);
  42.          result += args.output;
  43.        }
  44.  printf("Fibonacci of %d is %d.\n", n, result);
  45.  return 0;
  46.  }

       注意main里面的if(n<30),當(dāng)n在30以內(nèi)時,計算非???,就不需要使用多線程,當(dāng)n大于30之后,我們生成一個線程用來計算f(n-1),而main的主線程將繼續(xù)計算f(n-2),這樣等兩個線程都結(jié)束以后(pthread_join(thread, NULL);),我們將他們的結(jié)果相加。

 

      從這個例子就可以看出,自己實(shí)現(xiàn)線程的缺點(diǎn):

        1 這個例子正好可以用兩個線程分配在兩個核上來實(shí)現(xiàn),可如果一個任務(wù)需要16個線程同時執(zhí)行,我們又不知道客戶端到底是幾核的CPU時,這個任務(wù)如何分配就成為一個問題。

        2 這段代碼非常不簡潔

        3 額外的結(jié)構(gòu)和函數(shù)也破壞了算法本身的完整性。

 

下面我們使用多核支持庫來實(shí)現(xiàn)該代碼:


使用OpenMP

 

  1. int fib(int n) {
  2.   int i, j;
  3.   if (n<2)
  4.      return n;
  5.   else {
  6.     #pragma omp task shared(i)
  7.     i=fib(n-1);
  8.     #pragma omp task shared(j)
  9.     j=fib(n-2);
  10.     #pragma omp taskwait
  11.     return i+j;
  12.   }
  13. }

使用Cilk++

  1. int fib(int n) 
  2. {
  3.   if (n < 2) return n;
  4.  else {
  5.       int x = cilk_spawn fib(n-1);
  6.       int y = fib(n-2);
  7.       cilk_sync;
  8.       return x + y;
  9.      }
  10. }       
  11.                 
  12. int main(int argc, char *argv[])
  13. {       
  14.   int n = atoi(argv[1]);
  15.  int result = fib(n);
  16.  printf("Fibonacci of %d is %d.\n", n, result);
  17.  return 0;
  18. }

.NET Task Parallel Library中相應(yīng)的例子

  1.   Private Function FiboFullParallel(ByVal N As LongAs Long
  2.        If N <= 0 Then Return 0
  3.        If N = 1 Then Return 1
  4.    
  5.        Dim t1 As Tasks.Future(Of Long) = Tasks.Future(Of Long).Create( Function() FiboFullParallel(N - 1))
  6.        Dim t2 As Tasks.Future(Of Long) = Tasks.Future(Of Long).Create( Function() FiboFullParallel(N - 2))
  7.    
  8.        Return t1.Value + t2.Value
  9.    End Function

     可以看到無論使用哪種并發(fā)平臺,代碼都非常簡潔,沒有破壞原有的算法封裝,僅僅通過簡單的改造就可以實(shí)現(xiàn)自動任務(wù)的分派。

 


五、什么情況下該使用多核編程呢?

        如果一個任務(wù)的執(zhí)行時間在10-100毫秒,那么就無需使用多核,因?yàn)閷⑷蝿?wù)通過多線程分解到多核上計算,然后再將結(jié)果集合起來的開銷大致需要100毫秒(當(dāng)然具體多少依據(jù)機(jī)器的性能以及你所使用的編譯器的性能),而且還需要消耗內(nèi)存的空間。

        在OpenMP里面我們可以使用"if clause"來給雙核配置增加條件,例如下面的代碼很明顯,當(dāng)n小于100000的時候,不使用多核,當(dāng)n大于的時候再使用

  1. #pragma omp parallel for if(n > 100000)
  2. for (i = 0; i < n;, i++) {
  3. ...
  4. }

六、后記

       本文旨在告訴你為何要進(jìn)行多核開發(fā),以及簡單展示了多核開發(fā)平臺的使用。實(shí)際的多核開發(fā)要復(fù)雜的多,而且我們知道目前的PC機(jī)的多核系統(tǒng)都是基于共享內(nèi)存的,雖然每個核都有自己的一級緩存。因此不同核上的線程在運(yùn)行時就涉及到對資源競爭使用的問題。除此以外如果應(yīng)用需要用到IO(硬盤,網(wǎng)絡(luò))的時候,也存在同樣的問題。因此多核的設(shè)計的難點(diǎn)就在于需要具體情況具體分析,找出多核應(yīng)用的瓶頸,通過改進(jìn)數(shù)據(jù)結(jié)構(gòu)或算法,消除或優(yōu)化這個瓶頸。

 

 

發(fā)表于 @ 2008年11月21日 13:14:00|評論(6 )|收藏

 | 舊一篇: 在Windows下使用MingGW[GCC+OpenMP]和CodeBlocks開發(fā)多核應(yīng)用基本環(huán)境配置

評論

#zzz20005 發(fā)表于2008-11-22 22:42:15  IP: 123.6.255.*
學(xué)習(xí)了
#tingnt 發(fā)表于2008-11-23 00:31:54  IP: 122.94.224.*
學(xué)習(xí)一下
#tingnt 發(fā)表于2008-11-23 00:32:18  IP: 122.94.224.*
學(xué)習(xí)一下
#zhkzhk 發(fā)表于2008-11-23 09:23:21  IP: 125.71.95.*
樓主,好東西哦,我已經(jīng)學(xué)習(xí)了..
#fyt2008 發(fā)表于2008-11-23 09:46:34  IP: 125.46.10.*
學(xué)習(xí)了
#jarodpku 發(fā)表于2008-11-23 13:46:14  IP: 124.205.78.*
這個例子真是fdsafdsa,竟然用f(n)=f(n-1)+f(n-2)這樣的遞歸公式來舉例,重復(fù)計算太多,多核的效率根本無法體現(xiàn)。

還不如用優(yōu)化的串行程序來得快。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多