自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OpenMP中的數(shù)據(jù)處理子句

開發(fā) 前端
private子句用于將一個或多個變量聲明成線程私有的變量,變量聲明成私有變量后,指定每個線程都有它自己的變量私有副本,其他線程無法訪問私有副本。即使在并行區(qū)域外有同名的共享變量,共享變量在并行區(qū)域內(nèi)不起任何作用,并且并行區(qū)域內(nèi)不會操作到外面的共享變量。

10.1.1 private子句

private子句用于將一個或多個變量聲明成線程私有的變量,變量聲明成私有變量后,指定每個線程都有它自己的變量私有副本,其他線程無法訪問私有副本。即使在并行區(qū)域外有同名的共享變量,共享變量在并行區(qū)域內(nèi)不起任何作用,并且并行區(qū)域內(nèi)不會操作到外面的共享變量。

private子句的用法格式如下:

private(list)

下面便是一個使用private子句的代碼例子:

  1.  int k = 100
  2. #pragma omp parallel for private(k) 
  3.          for ( k=0; k < 10; k++) 
  4.          { 
  5.                    printf("k=%d/n", k); 
  6.          } 
  7.   
  8.          printf("last k=%d/n", k); 
  9. 上面程序執(zhí)行后打印的結(jié)果如下: 
  10. k=6 
  11. k=7 
  12. k=8 
  13. k=9 
  14. k=0 
  15. k=1 
  16. k=2 
  17. k=3 
  18. k=4 
  19. k=5 
  20. last k=100 

從打印結(jié)果可以看出,for循環(huán)前的變量k和循環(huán)區(qū)域內(nèi)的變量k其實是兩個不同的變量。

用private子句聲明的私有變量的初始值在并行區(qū)域的入口處是未定義的,它并不會繼承同名共享變量的值。

出現(xiàn)在reduction子句中的參數(shù)不能出現(xiàn)在private子句中。

10.1.2 firstprivate子句

private聲明的私有變量不能繼承同名變量的值,但實際情況中有時需要繼承原有共享變量的值,OpenMP提供了firstprivate子句來實現(xiàn)這個功能。

先看一下以下的代碼例子

  1. int k = 100
  2. #pragma omp parallel for firstprivate(k) 
  3.          for ( i=0; i < 4; i++) 
  4.          { 
  5.                    k+=i; 
  6.                    printf("k=%d/n",k); 
  7.          } 
  8.   
  9.          printf("last k=%d/n", k); 
  10.   

上面代碼執(zhí)行后打印結(jié)果如下:

k=100

k=101

k=103

k=102

last k=100

從打印結(jié)果可以看出,并行區(qū)域內(nèi)的私有變量k繼承了外面共享變量k的值100作為初始值,并且在退出并行區(qū)域后,共享變量k的值保持為100未變。

10.1.3 lastprivate子句

有時在并行區(qū)域內(nèi)的私有變量的值經(jīng)過計算 后,在退出并行區(qū)域時,需要將它的值賦給同名的共享變量,前面的private和firstprivate子句在退出并行區(qū)域時都沒有將私有變量的最后取 值賦給對應(yīng)的共享變量,lastprivate子句就是用來實現(xiàn)在退出并行區(qū)域時將私有變量的值賦給共享變量。

舉個例子如下:

  1. int k = 100
  2. #pragma omp parallel for firstprivate(k),lastprivate(k) 
  3.          for ( i=0; i < 4; i++) 
  4.          { 
  5.                    k+=i; 
  6.                    printf("k=%d/n",k); 
  7.          } 
  8.          printf("last k=%d/n", k); 

 上面代碼執(zhí)行后的打印結(jié)果如下:

  1. k=100 
  2. k=101 
  3. k=103 
  4. k=102 
  5. last k=103 

從打印結(jié)果可以看出,退出for循環(huán)的并行區(qū)域后,共享變量k的值變成了103,而不是保持原來的100不變。

由于在并行區(qū)域內(nèi)是多個線程并行執(zhí)行的, 最后到底是將那個線程的最終計算結(jié)果賦給了對應(yīng)的共享變量呢?OpenMP規(guī)范中指出,如果是循環(huán)迭代,那么是將最后一次循環(huán)迭代中的值賦給對應(yīng)的共享變 量;如果是section構(gòu)造,那么是最后一個section語句中的值賦給對應(yīng)的共享變量。注意這里說的最后一個section是指程序語法上的最后一 個,而不是實際運行時的最后一個運行完的。

如果是類(class)類型的變量使用在 lastprivate參數(shù)中,那么使用時有些限制,需要一個可訪問的,明確的缺省構(gòu)造函數(shù),除非變量也被使用作為firstprivate子句的參數(shù); 還需要一個拷貝賦值操作符,并且這個拷貝賦值操作符對于不同對象的操作順序是未指定的,依賴于編譯器的定義。

#p#

10.1.4 threadprivate子句

threadprivate子句用來指定全局的對象被各個線程各自復(fù)制了一個私有的拷貝,即各個線程具有各自私有的全局對象。

用法如下:

  1. #pragma omp threadprivate(list) new-line 

下面用threadprivate命令來實現(xiàn)一個各個線程私有的計數(shù)器,各個線程使用同一個函數(shù)來實現(xiàn)自己的計數(shù)。計數(shù)器代碼如下:

  1. int counter = 0
  2. #pragma omp threadprivate(counter) 
  3. int increment_counter() 
  4.          counter++; 
  5.          return(counter); 

如果對于靜態(tài)變量也同樣可以使用threadprivate聲明成線程私有的,上面的counter變量如改成用static類型來實現(xiàn)時,代碼如下:

  1. int increment_counter2() 
  2. static int counter = 0
  3. #pragma omp threadprivate(counter) 
  4.          counter++; 
  5.          return(counter); 

threadprivate和private的區(qū)別在于threadprivate聲明的變量通常是全局范圍內(nèi)有效的,而private聲明的變量只在它所屬的并行構(gòu)造中有效。

threadprivate的對應(yīng)只能用于copyin,copyprivate,schedule,num_threads和if子句中,不能用于任何其他子句中。

用作threadprivate的變量的地址不能是常數(shù)。

對于C++的類(class)類型變量,用作threadprivate的參數(shù)時有些限制,當(dāng)定義時帶有外部初始化時,必須具有明確的拷貝構(gòu)造函數(shù)。

對于windows系統(tǒng),threadprivate不能用于動態(tài)裝載(使用LoadLibrary裝載)的DLL中,可以用于靜態(tài)裝載的DLL中,關(guān)于windows系統(tǒng)中的更多限制,請參閱MSDN中有關(guān)threadprivate子句的幫助材料。

有關(guān)threadprivate命令的更多限制方面的信息,詳情請參閱OpenMP2.5規(guī)范。

10.1.5 shared子句

shared子句用來聲明一個或多個變量是共享變量。

用法如下:

shared(list)

需要注意的是,在并行區(qū)域內(nèi)使用共享變量時,如果存在寫操作,必須對共享變量加以保護(hù),否則不要輕易使用共享變量,盡量將共享變量的訪問轉(zhuǎn)化為私有變量的訪問。

循環(huán)迭代變量在循環(huán)構(gòu)造區(qū)域里是私有的。聲明在循環(huán)構(gòu)造區(qū)域內(nèi)的自動變量都是私有的。

10.1.6 default子句

default子句用來允許用戶控制并行區(qū)域中變量的共享屬性。

用法如下:

default(shared | none)

使用shared時,缺省情況下,傳入并行區(qū)域內(nèi)的同名變量被當(dāng)作共享變量來處理,不會產(chǎn)生線程私有副本,除非使用private等子句來指定某些變量為私有的才會產(chǎn)生副本。 如果使用none作為參數(shù),那么線程中用到的變量必須顯示指定是共享的還是私有的,除了那些由明確定義的除外。

10.1.7 reduction子句

reduction子句主要用來對一個或多個參數(shù)條目指定一個操作符,每個線程將創(chuàng)建參數(shù)條目的一個私有拷貝,在區(qū)域的結(jié)束處,將用私有拷貝的值通過指定的運行符運算,原始的參數(shù)條目被運算結(jié)果的值更新。

reduction子句用法如下:

reduction(operator:list)

下表列出了可以用于reduction子句的一些操作符以及對應(yīng)私有拷貝變量缺省的初始值,私有拷貝變量的實際初始值依賴于redtucion變量的數(shù)據(jù)類型。

表10-4-1:reduction操作中各種操作符號對應(yīng)拷貝變量的缺省初始值

Operator

Initialization value
+ 0
*
1
- 0
& ~0
| 0
^ 0
&& 1
|| 0

 例如一個整數(shù)求和的程序如下:

  1. int i, sum = 100
  2.   
  3. #pragma omp parallel for reduction(+: sum) 
  4. for ( i = 0; i < 1000; i++ ) 
  5.  sum += i; 
  6.   
  7. printf( "sum = %ld/n", sum);

注意,如果在并行區(qū)域內(nèi)不加鎖保護(hù)就直接對共享變量進(jìn)行寫操作,存在數(shù)據(jù)競爭問題,會導(dǎo)致不可預(yù)測的異常結(jié)果。共享數(shù)據(jù)作為private、firstprivate、lastprivate、threadprivate、reduction子句的參數(shù)進(jìn)入并行區(qū)域后,就變成線程私有了,不需要加鎖保護(hù)了。

#p#

10.1.8copyin子句

copyin子句用來將主線程中threadprivate變量的值拷貝到執(zhí)行并行區(qū)域的各個線程的threadprivate變量中,便于線程可以訪問主線程中的變量值,

用法如下:

  1. copyin(list) 

 copyin中的參數(shù)必須被聲明成threadprivate的,對于類類型的變量,必須帶有明確的拷貝賦值操作符。

對于前面threadprivate中講過的計數(shù)器函數(shù),如果多個線程使用時,各個線程都需要對全局變量counter的副本進(jìn)行初始化,可以使用copyin子句來實現(xiàn),示例代碼如下:

  1. int main(int argc, char* argv[]) 
  2.          int iterator; 
  3. #pragma omp parallel sections copyin(counter) 
  4.          { 
  5. #pragma omp section 
  6.                    { 
  7.                             int count1; 
  8.                             for ( iterator = 0; iterator < 100; iterator++ ) 
  9.                             { 
  10.                                      count1 = increment_counter(); 
  11.                             } 
  12.                             printf("count1 = %ld/n", count1); 
  13.                    } 
  14. #pragma omp section 
  15.                    { 
  16.                             int count2; 
  17.                             for ( iterator = 0; iterator < 200; iterator++ ) 
  18.                             { 
  19.                                      count2 = increment_counter(); 
  20.                             } 
  21.                             printf("count2 = %ld/n", count2); 
  22.                    } 
  23.          } 
  24.          printf("counter = %ld/n", counter); 

打印結(jié)果如下:

count1 = 100

count2 = 200

counter = 0

10.1.9 copyprivate子句

copyprivate子句提供了一種機(jī)制用一個私有變量將一個值從一個線程廣播到執(zhí)行同一并行區(qū)域的其他線程。

用法如下:

copyprivate(list)

copyprivate子句可以關(guān)聯(lián)single構(gòu)造,在single構(gòu)造的barrier到達(dá)之前就完成了廣播工作。copyprivate可以對privatethreadprivate子句中的變量進(jìn)行操作,但是當(dāng)使用single構(gòu)造時,copyprivate的變量不能用于privatefirstprivate子句中。

下面便是一個使用copyprivate的代碼例子:

  1. int counter = 0
  2. #pragma omp threadprivate(counter) 
  3. int increment_counter() 
  4.          counter++; 
  5.          return(counter); 
  6. #pragma omp parallel 
  7.          { 
  8.                    int    count; 
  9. #pragma omp single copyprivate(counter) 
  10.                    { 
  11.                             counter = 50
  12.                    } 
  13.                    count = increment_counter(); 
  14.                    printf("ThreadId: %ld, count = %ld/n", omp_get_thread_num(), count); 

打印結(jié)果為:

ThreadId: 2, count = 51

ThreadId: 0, count = 51

ThreadId: 3, count = 51

ThreadId: 1, count = 51

如果沒有使用copyprivate子句,那么打印結(jié)果為:

ThreadId: 2, count = 1

ThreadId: 1, count = 1

ThreadId: 0, count = 51

ThreadId: 3, count = 1

從打印結(jié)果可以看出,使用copyprivate子句后,single構(gòu)造內(nèi)給counter賦的值被廣播到了其他線程里,但沒有使用copyprivate子句時,只有一個線程獲得了single構(gòu)造內(nèi)的賦值,其他線程沒有獲取single構(gòu)造內(nèi)的賦值。

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

 

責(zé)任編輯:陳四芳 來源: blog.csdn.net
相關(guān)推薦

2025-01-07 13:58:08

SQL數(shù)據(jù)處理函數(shù)數(shù)據(jù)庫

2014-06-05 09:29:03

數(shù)據(jù)處理

2013-12-17 10:15:19

OpenMP任務(wù)調(diào)度

2025-01-27 12:19:51

2017-07-21 14:22:17

大數(shù)據(jù)大數(shù)據(jù)平臺數(shù)據(jù)處理

2023-07-31 08:21:22

語法校對器Pick

2019-10-12 05:17:11

物聯(lián)網(wǎng)大數(shù)據(jù)IOT

2010-04-08 13:55:18

Oracle數(shù)據(jù)處理

2015-08-27 13:15:03

2024-01-31 23:22:35

vaexPython

2016-12-13 11:48:05

數(shù)據(jù)處理不平衡數(shù)據(jù)

2018-12-07 14:50:35

大數(shù)據(jù)數(shù)據(jù)采集數(shù)據(jù)庫

2020-11-02 15:56:04

大數(shù)據(jù)數(shù)據(jù)庫技術(shù)

2023-11-29 13:56:00

數(shù)據(jù)技巧

2010-04-12 11:12:53

Oracle數(shù)據(jù)處理

2018-08-14 11:05:25

2019-10-10 17:53:36

大數(shù)據(jù)平臺架構(gòu)LambdaKappa

2024-02-07 09:25:52

數(shù)據(jù)處理快手大模型

2015-11-09 09:58:31

大數(shù)據(jù)Lambda架構(gòu)

2023-12-13 10:22:04

APISpark數(shù)據(jù)
點贊
收藏

51CTO技術(shù)棧公眾號