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

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 閱讀(623) 評論(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>
            国产亚洲精品aa午夜观看| 久久精品国产精品亚洲精品| 欧美电影免费网站| 午夜精品久久久久久久久久久久久 | 99精品国产一区二区青青牛奶| 亚洲一区二区精品视频| 亚洲第一综合天堂另类专| 亚洲一区二区免费在线| 国产精品久久影院| 亚洲欧美亚洲| 亚洲永久免费视频| 伊人婷婷久久| 亚洲丰满在线| 欧美日韩高清不卡| 免费一级欧美片在线播放| 中文欧美字幕免费| 国产欧美一区二区三区沐欲| 久久精品亚洲乱码伦伦中文| 欧美一区激情| 亚洲免费成人av| 一区二区三区蜜桃网| 99综合在线| 激情综合中文娱乐网| 欧美成人免费视频| 亚洲剧情一区二区| 国产亚洲精品激情久久| 亚洲国产精品嫩草影院| 国产精品乱码一区二区三区| 久久er精品视频| 欧美成人激情视频免费观看| 亚洲欧美日韩国产综合在线 | 一区在线视频观看| 亚洲理伦电影| 在线电影欧美日韩一区二区私密| 日韩性生活视频| 亚洲福利国产精品| 亚洲一区二区在线| 99re视频这里只有精品| 欧美一区激情| 欧美一区免费视频| 国产精品久久毛片a| 亚洲人成小说网站色在线| 在线精品国精品国产尤物884a| 久久一区二区三区四区五区| 国产伦理精品不卡| 亚洲午夜免费视频| 欧美一区二区视频免费观看| 欧美国产日韩一区| 亚洲人屁股眼子交8| 亚洲人成精品久久久久| 欧美福利电影网| 久久视频免费观看| 在线播放中文一区| 麻豆成人在线播放| 亚洲国产精品热久久| 欧美激情一区在线| 亚洲精品视频啊美女在线直播| 亚洲精品日韩在线观看| 欧美日韩国产在线播放网站| 一区二区三区回区在观看免费视频| 亚洲国产精品一区在线观看不卡| 久久米奇亚洲| 亚洲精品久久久久中文字幕欢迎你| 亚洲免费福利视频| 国产欧美精品日韩| 裸体丰满少妇做受久久99精品| 亚洲精品色婷婷福利天堂| 欧美制服第一页| 亚洲黄色成人网| 久久艳片www.17c.com| 99热这里只有成人精品国产| 久久久久久免费| 亚洲视频在线观看三级| 亚洲大片免费看| 欧美在线国产精品| 夜夜爽www精品| 亚洲第一网站| 欧美电影免费观看高清| 欧美一区激情| 亚洲欧美综合v| av不卡在线| 日韩一区二区精品| 亚洲精品视频二区| 韩国av一区| 一区二区三区在线视频播放| 欧美大尺度在线| 美女网站在线免费欧美精品| 久久久久欧美精品| 亚洲欧美久久| 欧美中文字幕在线观看| 久久久综合网站| 欧美色综合网| 国产在线观看91精品一区| 国产有码一区二区| 亚洲欧洲日夜超级视频| 欧美午夜片欧美片在线观看| 欧美特黄a级高清免费大片a级| 国产麻豆成人精品| 在线观看91精品国产入口| 99精品免费视频| 久久精品理论片| 亚洲人成7777| 欧美一区二区视频免费观看| 久久一区二区三区超碰国产精品| 欧美日韩不卡| 精品动漫3d一区二区三区免费版 | 久久久精品一品道一区| 久久久久久久久久久久久女国产乱 | 国产嫩草一区二区三区在线观看| 美女图片一区二区| 欧美高清自拍一区| 久久九九精品| 国产资源精品在线观看| 亚洲制服欧美中文字幕中文字幕| 亚洲国产成人在线| 裸体丰满少妇做受久久99精品| 国产一区二区成人| 午夜视频久久久久久| 99成人在线| 国产精品嫩草99av在线| 亚洲一区欧美激情| 亚洲美女黄网| 欧美视频三区在线播放| 在线亚洲成人| 亚洲欧美日韩精品| 国产一区二区日韩精品| 久久久久久久性| 另类尿喷潮videofree| 亚洲激情一区二区三区| 亚洲国产精品悠悠久久琪琪| 毛片一区二区三区| 久久香蕉国产线看观看网| 禁断一区二区三区在线| 久久米奇亚洲| 欧美精品一区三区在线观看| 亚洲男人第一网站| 午夜久久黄色| 亚洲日本欧美| 欧美一级免费视频| 亚洲精品亚洲人成人网| 午夜日韩在线观看| 亚洲精品免费电影| 亚洲一区免费网站| 亚洲高清视频在线| 香蕉久久一区二区不卡无毒影院 | 欧美成人午夜剧场免费观看| 日韩亚洲成人av在线| 亚洲欧美自拍偷拍| 亚洲调教视频在线观看| 午夜视频精品| 欧美在线视频日韩| 欧美日本久久| 亚洲第一福利视频| 国内外成人免费激情在线视频网站| 亚洲高清资源| 亚洲电影有码| 久久久噜噜噜久久狠狠50岁| 亚洲免费在线播放| 小处雏高清一区二区三区| 亚洲天堂免费在线观看视频| 欧美高清视频一区| 亚洲电影视频在线| 99re6热在线精品视频播放速度 | 国产一区二区三区黄视频| 正在播放亚洲| 亚洲欧美伊人| 国产精品亚洲欧美| 欧美在线你懂的| 久久人人97超碰精品888| 韩国成人福利片在线播放| 久久免费国产精品| 亚洲黄色一区| 欧美日韩一区免费| 欧美一区二区三区另类| 美女图片一区二区| 最近看过的日韩成人| 欧美女同在线视频| 亚洲欧美成人在线| 亚洲黄色小视频| 欧美尤物巨大精品爽| 国内精品久久久久久久影视蜜臀| 麻豆国产精品777777在线| 亚洲国产综合91精品麻豆| 亚洲综合精品自拍| 亚洲国产精品ⅴa在线观看| 欧美激情一二三区| 亚洲一区免费看| 欧美aⅴ99久久黑人专区| 日韩亚洲视频| 亚洲成色www久久网站| 欧美另类视频| 亚洲人成毛片在线播放女女| 午夜精品久久久久影视| 在线观看日韩av电影| 欧美成人一二三| 篠田优中文在线播放第一区| 免费成人美女女| 亚洲国产精品嫩草影院| 一区二区亚洲精品| 国产精品少妇自拍|