青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++ Coder

HCP高性能計算架構,實現,編譯器指令優化,算法優化, LLVM CLANG OpenCL CUDA OpenACC C++AMP OpenMP MPI

C++博客 首頁 新隨筆 聯系 聚合 管理
  98 Posts :: 0 Stories :: 0 Comments :: 0 Trackbacks
http://blog.csdn.net/bendanban/article/details/6303100

   openMP并不是只能對循環來并行的,循環并行化單獨拿出來說是因為它在科學計算中非常有用,比如向量、矩陣的計算。所以我單獨拿出這一部分給大家講講。這里主要講解的是for循環。

編譯指導語句:

    一般格式:

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

    for(index = first; qualification; index_expr)

    {…}

    第一句中[]的部分是可選的,由自己的程序并行特點而定。大家先不要把精力放到這里面。后面的文章中會繼續講解的。

并行化for的編寫規則

    1、index的值必須是整數,一個簡單的for形式:for(int i = start; i < end; i++){…} 。

    2、start和end可以是任意的數值表達式,但是它在并行化的執行過程中值不能改變,也就是說在for并行化執行之前,編譯器必須事先知道你的程序執行多少次,因為編譯器要把這些計算分配到不同的線程中執行。

    3、循環語句只能是單入口但出口的。這里只要你避免使用跳轉語句就行了。具體說就是不能使用goto、break、return。但是可以使用continue,因為它并不會減少循環次數。另外exit語句也是可以用的,因為它的能力太大,他一來,程序就結束了。

例子講解

例1、for循環并行:

#include 
#include 
"omp.h" 
int main(int argc, char* argv[]) 

    
int i; 
    #pragma omp parallel 
for 
    
for (i = 0; i < 12; i++
    
{        printf("i = %d  %d/n", i, omp_get_thread_num());    } 
    
return 0
}

 

例1的執行結果如圖1所示:

image

圖1、例1的執行結果

從結果中可以看出 i 屬于{0,1,2}時由0號線程執行,i 屬于{3,4,5}時由1號線程執行,i 屬于{6,7,8}時由2號線程執行,i 屬于{9,10,11}時由3號線程執行。omp_get_thread_num()這個函數通過執行結果大家也知道了,他返回每個線程的編號。

并行編譯子句

    openMP中有多種并行化子句,這些子句都是為控制循環并行化編譯而設定的,這里我們主要關注數據作用域子句,這里的數據作用域是指各個線程是否對某一變量有權訪問。shared子句用來標記變量在各個線程之間是共享的,private子句標記變量在各個線程之間是私有的,實際上它會在在每個線程中保存一個副本。默認情況下,并行執行的變量是共享的。至于其它編譯子句將在后面的文章中介紹。

用實例講解數據作用域子句

實際上我很難想到一個綜合的例子來講解這種子句的限制異同,所以我寫了幾個例子。

例2、private

#include
#include "omp.h"
int main(int argc, char* argv[])
{
    float x = 4.3f;
    int i;
    #pragma omp parallel for private(x)
    for (i = 0; i < 12; i++)
    {
        x = 0;
        printf("parallel x = %.1f, thread nummber:%d/n", x, omp_get_thread_num());
    }
    printf("/nserial   x = %.1f, thread nummber:%d/n", x, omp_get_thread_num());
    return 0;
}

image

圖2、例2執行結果

例3 firstprivate(var):指定var在每個線程中都有一個副本,并且var的初始值在并行執行開始之前定義,每個并行線程的var的副本初值就是串行時定義的初始值。程序結束后串行程序中的var值并不會改變。

#include 
#include 
"omp.h" 
int main(int argc, char* argv[]) 

    
float x = 4.3f
    
int i; 
    #pragma omp parallel 
for firstprivate(x) 
    
for (i = 0; i < 12; i++
    

        x 
+= 1.0f
        printf(
"parallel x = %.1f, thread nummber:%d/n", x, omp_get_thread_num());        
    }
 
    printf(
"/nserial   x = %.1f, thread nummber:%d/n", x, omp_get_thread_num()); 
    
return 0
}

 

 

image

圖3、例3的執行結果

例4 lastprivate(var):指定最后多線程執行完后原串行循環最后一次var的值帶到主線程(串行部分)

#include 
#include 
"omp.h" 
int main(int argc, char* argv[]) 

    
float x = 4.3f
    
int i; 
    #pragma omp parallel 
for lastprivate(x) 
    
for (i = 0; i < 12; i++
    
{        
        x 
= 0.0f
        printf(
"parallel x = %.1f, thread nummber:%d/n", x, omp_get_thread_num());        
    }
 
    printf(
"/nserial   x = %.1f, thread nummber:%d/n", x, omp_get_thread_num()); 
    
return 0
}

image

圖4、例4的執行結果

例5 firstprivate與lastprivate聯用,很奇怪openMP很多情況下是不允許某個變量被指定兩次規則的,他倆卻可以,呵呵,而且配合效果還不錯。

#include 
#include 
"omp.h" 
int main(int argc, char* argv[]) 

    
float x = 4.3f
    
int i; 
    #pragma omp parallel 
for firstprivate(x) lastprivate(x) 
    
for (i = 0; i < 12; i++
    
{        
        x 
+= (float)omp_get_thread_num(); 
        printf(
"parallel x = %.1f, thread nummber:%d/n", x, omp_get_thread_num());        
    }
 
    printf(
"/nserial   x = %.1f, thread nummber:%d/n", x, omp_get_thread_num()); 
    
return 0
}

image

圖5、例5的執行結果

    從上面的例2、3的程序中可以看出例2中每個線程中x都是私有的,它屬于每個線程,在主線程的定義并不能帶入到各個線程中,使用firstprivate后,x在主線程的初始值可以帶到各個線程中,在圖3可以看出每個線程x的輸出結果實際是相同的,但是在并行執行結束后,主線程中的x值仍然為4.3。從例4的執行結果可以看出最后x的值帶出到了主線程中,這個x值到底是哪個線程中的哪?答案是最后一句x賦值后的值,哪個線程執行完的最晚就是哪個x的值。例5顯示firstprivate與lastprivate聯合使用的執行結果。

例6 reduction規約操作,

    執行reduction的變量要特別注意,以reduction(+:sum)為例。

    第一種情況:sum為局部變量。這是你必須為sum在串行程序中賦初值,sum 被設置為每個線程私有,先各自執行完算出各自的sum值,最后主線程會將 《線程數+1》個sum變量規約,比如你num_thread(4),在開始并行執行之前你對規約變量賦初值為10,并行時假設每個線程算的的sum值為1,那么最終sum帶到串行程序中的變量值為14(串行的10+四個線程的1)。

    第二種情況:sum為全局變量。這是你不必為sum賦初始值,因為此時默認串行的sum值為0,進入每個線程的sum值也是0,規約時仍然是將《線程數+1》個sum值相加,因為你并沒有對全局的sum賦初值,所以最后規約的結果看著像是只有各線程的sum參加了規約操作。其實當你將全局的sum賦初值時,你會發現最后規約的sum值又多加了全局變量sum的串行程序結果。

    重要提醒:不管你怎樣設計sum的串行聲明形式,只要他在被定義為規約變量,每次進入并行線程的sum值都是0;

    也許你想把每個并行線程的sum值初始化成一個非0的值,然后再各自線程中在使用,那么我可以告訴你,別想了(至少我沒有做到)。因為我規約sum值,如果這個規約有意義你的每個線程應該是各自獨立未回各自的sum的,那么這個初始值使用0就已經非常好了,因為各自的sum計算如果結果一樣,你為何不直接用一句乘法哪(線程數*一個線程計算的sum值)。

#include 
#include 
"omp.h" 
int main(int argc, char* argv[]) 

    
float x = 0.0f
    
int i; 
    
float sum = 0.0f
#pragma omp parallel 
for private(x) reduction(+:sum) 
    
for (i = 0; i < 12; i++
    
{        
        x 
= (float)omp_get_thread_num(); 
        sum 
+= x; 
        printf(
"parallel sum = %.1f, thread nummber:%d/n", sum, omp_get_thread_num());        
    }
 
    printf(
"/nserial   sum = %.1f, thread nummber:%d/n", sum, omp_get_thread_num()); 
    
return 0
}

image

圖6、例6執行結果

    在例6中我使用了reduction(+:sum),這表示每個線程對sum這個共享變量執行加操作時其它任何線程不能對它進行加操作,實際上我們這樣理解是有偏差的,真正的機理在執行結果中不難看出,實際每個線程都拷貝了一個sum的副本,先在自己執行時加完sum,等所有線程都執行結束后,主線程再將每個線程的sum副本的值加起來返回給主線程中sum。

小結

    本節主要講述了for語句的并行化。現在為止大家應該可以熟練使用for并行化了。文章中可能還有些不全面的地方,熱切期望各位讀者能給出批評和指正,期待中……


posted on 2012-10-21 11:54 jackdong 閱讀(617) 評論(0)  編輯 收藏 引用 所屬分類: OPenMP
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产在线一区二区三区四区| 亚洲精品国久久99热| 国产欧美欧美| 一本色道久久综合一区| 免费不卡中文字幕视频| 性色av一区二区三区红粉影视| 欧美日韩免费一区二区三区视频| 亚洲第一网站| 欧美大片国产精品| 久久综合九色欧美综合狠狠| 国内精品免费在线观看| 久久久999精品| 欧美一区视频在线| 狠狠色丁香婷婷综合| 久久久久国产精品人| 久久电影一区| 一区二区在线免费观看| 浪潮色综合久久天堂| 久久久999| 亚洲国产高清一区| 亚洲国产精品成人一区二区| 久久久亚洲综合| 影音国产精品| 亚洲第一在线综合网站| 欧美理论电影在线观看| 亚洲视频1区| 亚洲欧美日本国产有色| 国产日韩欧美成人| 老牛国产精品一区的观看方式| 久久久久国内| 99精品视频免费观看视频| 一区二区三区**美女毛片| 国产精品久久久久久影院8一贰佰| 亚洲欧美日韩在线不卡| 欧美亚洲一区三区| 亚洲人成免费| 亚洲影视综合| 在线观看日韩av电影| 亚洲国产日韩欧美在线图片 | 欧美日韩亚洲精品内裤| 亚洲欧美国产制服动漫| 久久国产精彩视频| 亚洲精品视频在线观看免费| 一区二区三区成人精品| 国产综合色产| 亚洲精品裸体| 国产一区二区精品在线观看| 欧美成人精品一区| 欧美亚日韩国产aⅴ精品中极品| 久久精品30| 欧美激情在线免费观看| 性xx色xx综合久久久xx| 麻豆免费精品视频| 欧美三级电影大全| 久久福利精品| 欧美日韩性生活视频| 久久久精品一区| 欧美极品一区| 久色婷婷小香蕉久久| 欧美日韩在线播放一区二区| 久久人体大胆视频| 国产精品99免视看9| 亚洲福利视频专区| 国产在线一区二区三区四区| 日韩亚洲欧美中文三级| 亚洲国产黄色| 久久国产天堂福利天堂| 午夜激情亚洲| 欧美日韩视频一区二区| 欧美成人午夜剧场免费观看| 国产欧美一区二区三区在线老狼 | 最新国产乱人伦偷精品免费网站| 亚洲尤物视频在线| 一本色道久久综合亚洲精品不| 久久久久成人精品免费播放动漫| 亚洲一级一区| 欧美激情偷拍| 亚洲第一搞黄网站| 亚洲成人在线免费| 午夜激情一区| 羞羞色国产精品| 欧美调教vk| 99伊人成综合| 亚洲少妇中出一区| 欧美日韩国产色视频| 欧美激情中文字幕乱码免费| 狠狠色2019综合网| 久久精品99国产精品| 欧美中文字幕第一页| 国产精品久久激情| 在线中文字幕一区| 亚洲欧美国产毛片在线| 国产精品99一区| 亚洲影院色在线观看免费| 亚洲欧美区自拍先锋| 国产精品二区影院| 亚洲一区免费| 久久精品91| 激情综合自拍| 麻豆精品在线播放| 亚洲经典在线看| 一区二区三区欧美日韩| 欧美日韩综合一区| 亚洲男人影院| 久久精品夜色噜噜亚洲aⅴ| 国产综合第一页| 久久人人爽人人| 欧美激情精品久久久久久久变态| 亚洲激情国产| 欧美日韩国产91| 亚洲影院色在线观看免费| 久久久91精品国产| 亚洲高清久久久| 欧美日韩1区2区3区| 亚洲午夜精品网| 久热国产精品视频| 亚洲毛片一区| 久久久精品欧美丰满| 欧美国产日韩一区二区三区| 99视频精品在线| 国产精品最新自拍| 久久一二三四| 一区二区三区www| 久久综合伊人77777麻豆| 99国产精品久久久久久久| 国产精品日韩精品欧美在线 | 国产精品一区二区在线观看网站| 欧美在线中文字幕| 亚洲精品婷婷| 久久久999精品免费| 亚洲日本在线观看| 国产日韩精品久久久| 欧美va日韩va| 亚洲在线观看| 亚洲国产精品一区二区久| 亚洲欧美视频在线观看视频| 精品999网站| 国产精品久久国产精麻豆99网站| 久久久午夜精品| 亚洲一区视频在线| 亚洲国产精彩中文乱码av在线播放| 亚洲午夜一二三区视频| 在线观看欧美一区| 国产亚洲二区| 国产精品成人播放| 欧美大片专区| 久久久久久久久一区二区| 99香蕉国产精品偷在线观看| 欧美大片免费久久精品三p| 午夜国产精品影院在线观看| 亚洲精品中文字幕有码专区| 国产日韩欧美一区二区| 欧美日韩在线电影| 欧美粗暴jizz性欧美20| 久久精品国产视频| 亚洲欧美在线磁力| 亚洲制服丝袜在线| 国产精品99久久99久久久二8 | 一本色道久久加勒比精品| 狠狠久久婷婷| 国产在线麻豆精品观看| 国产精品久99| 国产精品啊啊啊| 欧美日本一区| 欧美国产精品中文字幕| 久久久999国产| 久久久久国色av免费看影院| 香蕉久久国产| 亚洲欧美精品中文字幕在线| 一区二区三欧美| 在线中文字幕不卡| 亚洲午夜黄色| 亚洲欧美日本国产专区一区| 国产精品99久久久久久有的能看| 亚洲乱码精品一二三四区日韩在线 | 韩国三级电影久久久久久| 国产喷白浆一区二区三区| 国产精品视频久久| 国产精品资源| 国产一区二区三区最好精华液| 国产精品自拍三区| 国产一区白浆| 一区在线播放| 欧美精品一区二区三区久久久竹菊| 久久综合久久综合久久| 久久综合久久综合九色| 欧美高清视频在线观看| 欧美精品啪啪| 国产精品国产三级国产专播精品人 | 亚洲欧美久久久| 欧美在线视频一区二区三区| 欧美中文字幕在线视频| 久久理论片午夜琪琪电影网| 久久免费精品视频| 欧美成人精品在线观看| 欧美日韩成人综合天天影院| 国产精品九色蝌蚪自拍| 国内精品美女在线观看| 亚洲免费不卡| 久久激情视频|