多核多線程技術(shù)編程_第1頁
多核多線程技術(shù)編程_第2頁
多核多線程技術(shù)編程_第3頁
多核多線程技術(shù)編程_第4頁
多核多線程技術(shù)編程_第5頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、兒年之侃,cpu的性能還主要取決于cpu的主頻,經(jīng)過超摩爾定律的發(fā)展后,沒過多長 吋間cpu的主頻速度就已接近“極限”,使得單單靠提高cpu的主頻來提升性能變得非常困 難。h前,intel, amd等cpu生產(chǎn)商都轉(zhuǎn)而采川了多核技術(shù)來提升cpu性能,其至提出了 群核cpu的概念。這意味著,要充分發(fā)揮多核cpu的性能,程序就必須采用多線程并發(fā)計(jì)算 的方式,傳統(tǒng)的串行程序?qū)O大地浪費(fèi)多核cpu的運(yùn)算能力!c+是上世紀(jì)80年代誕生的語言,它的前身是同樣風(fēng)靡全球的c語言。一直以來它都以 代碼效率卓越著稱,進(jìn)入多核時(shí)代fi,因?yàn)閏+標(biāo)準(zhǔn)庫沒有提供多線程支持,要用c+開發(fā) 出充分利用多核cpu的程序?qū)t

2、臨很大挑戰(zhàn)。干是,在c+社區(qū)岀現(xiàn)了不少優(yōu)秀的庫以支持并行編程,如各種跨平臺的線程庫,open mp, clik+等。另一方面,微軟也從win2k開始不斷地加入線程池api (如queueuserwork item) , c+09標(biāo)準(zhǔn)也明確地表示要加入多線程的支持。使川線程庫編寫并行程序的優(yōu)點(diǎn)是可以精確調(diào)度各個(gè)線程,并.r.可以在所冇c+編譯器 垠使用。不過耍充分發(fā)揮多核cpu的性能,還??紤]很多w素,主耍難點(diǎn)有: 死鎖 編寫多線程必然會遇到m步問題,如染m步控制出現(xiàn)問題,就討能出現(xiàn)死 鎖或臟數(shù)據(jù)。 線程之間通信 使川何種機(jī)制在多個(gè)線程之間通信?即要保證通信數(shù)據(jù)同步乂要 保證效率。 負(fù)載平衡分配

3、到每個(gè)線程的工作量要盡量平衡,避免一個(gè)線程忙一個(gè)線程閑的怙形發(fā)生。 資源匹配程序應(yīng)該使用多少個(gè)線程?過少的線程不能充分利用cpu的多核優(yōu)勢,而過多的線程會造成線程凋度過于頻繁同樣會降低效率。openmp是目前比較流行的c+并行編程方式,它通過在代碼巾插入專用的pragma編譯 指令來指示編譯器把串行代碼編譯成丼行程序。它的優(yōu)點(diǎn)是易于使用,幾乎不用修改原代碼就可對老程序進(jìn)行并發(fā)文待的改造。問題 是它必須要有編澤器的支持,盡管目前不少編譯器都提供了 openmp的支持,侃它畢竟不 是c+的-部分,甚至它都不是真正意義上的c+庫。現(xiàn)在,我們又有了一個(gè)新選擇:intel thread building

4、 blocks(tbb,線程構(gòu)建模塊)。 tbb是一個(gè)開源的c+模板庫,能夠運(yùn)行在windows、linux、macintosh以及unix等系統(tǒng) 上,只要是標(biāo)準(zhǔn)的c+編譯器都可以使用它。以不足程序測試的實(shí)驗(yàn)案例和測試結(jié)果: for ( int j = 0; j < nuin; j+ )kj=j;for (int p=0;p<10000;p+)cout (p); /進(jìn)行很大的for循環(huán),又調(diào)用函數(shù),主要 n的就是讓它耗時(shí)間;for (int i=0; i<num; i+)/順序輸出 0-99;printf ("%d ", ki);很顯然,這是一個(gè)經(jīng)典的單線

5、程程序,其中的for(int p=0;p10000;p+)cout(p);是 一個(gè)內(nèi)嵌了提高程序復(fù)雜性的函數(shù)的人循環(huán),主要是為了提尚程序的額外幵銷,以便于我們 能夠明顯的觀察到多線程程序與單線程程序之間的性能差異。整個(gè)for程序執(zhí)行的流程如卜 所示:j=0 -> kj=j -進(jìn)行復(fù)雜運(yùn)算_j! =j+并繼續(xù)下一個(gè)循環(huán)mam-1 ?:退出循環(huán) 并順序顯示k nuni中的內(nèi)容有一點(diǎn)需耍注意的是,由于單線程的程序是順序執(zhí)行的,所以上而這個(gè)程序笫二個(gè)for 語句其實(shí)是可以不必使用的,可以將它內(nèi)嵌入第一個(gè)for語句中:for ( int j = 0; j < num; j+ )for (in

6、t p=0;p<10000;p+)cout(p); /進(jìn)行很大的for循環(huán),又調(diào)用函數(shù),主要 目的就是讓它耗時(shí)間;printf (%d ", ki);這樣nj以減少程序額外開銷,但是對于多線程程序來說,這點(diǎn)開銷是必須的,如果輸出 必須是順序的話,那我們有必耍控制它的輸出順序,否則將會hi現(xiàn)亂序輸hi-盡管結(jié)果是:lh: 確的,假是輸出的順序卻足我們不想看到的。當(dāng)然,第二個(gè)for語句所增加的開銷,遠(yuǎn)遠(yuǎn)比 不上外行稅序運(yùn)行吋所節(jié)約的開銷。我們使川intel的openmp技術(shù)來創(chuàng)建多線程的程序, 因?yàn)閛penmp技術(shù)夠良觀,也很界易去分析與理解,所以我們無需去調(diào)用底層apt就能夠輕

7、易的實(shí)現(xiàn)多線程編程。要使用openmp技術(shù)就要安裝intel編譯器及下的openmp組件, intel編譯器可以很好的與visual stdio整合在一起,起碼要求是你的計(jì)算機(jī)上必須安裝 了 visual 0+6.0。當(dāng)然,安裝完之后我們必須進(jìn)行一些設(shè)置,以visual stdio 2008為例, 如果我們想要使用openi叩技術(shù)的話,我們須在vc項(xiàng)目下右邊的“資源管理器”屮點(diǎn)“屬 性”一“c/c+” 一 “語言”-有個(gè)“opernnp支持”選項(xiàng),選“是(/openmp) ”即可。另 外我們必須在程序中插入omp. h的頭文件。做完了最基木的設(shè)置之v;,我們就可以丌始改程序了:pragma o

8、mp parallel for/就多了這么一么j,在我的電腦上就快了 75%;for ( int j = 0; j < num; j+ )for(int p=0;p<10000;p+)cout(p):for(int i=0;i<num;i+) printf("%d ",ki);這就可以了,我們發(fā)現(xiàn),僅僅只是多了一條“#pragma omp parallel for”而已,但是 就多了這么一川,就是程序在我的汁算機(jī)上快了近75% (估測,非精確計(jì)算)。原先程序使 用丫近32秒,但是現(xiàn)在程序僅用丁 8秒,這證明了程序運(yùn)行確實(shí)是大幅提高丁性能。那我 們該著么理解

9、這僅多出來的一條語句呢?很簡單,這兄然是編譯器控制桁令,它會在程序編 譯的吋候自動分析for語句,將它拆成多個(gè)線程來運(yùn)行。這樣做的好處是我們能夠很簡單的 就創(chuàng)建多線程程序而無需去了解其底層的運(yùn)行機(jī)制,但是它也有一些局限性,使得我們不得 不考慮以下幾個(gè)問題:1. 對for語句我們必須使川for (i=xxx; x或xxx; i的運(yùn)算法則不能含有變景)其屮 xxx力固®的常數(shù)的形式的循環(huán)i能夠使用郎1113 omp parallel for (當(dāng)然sections結(jié) 構(gòu)也吋以進(jìn)行拆分),也就是說在需耍進(jìn)行多線程化的循環(huán)必須是定長的、nf預(yù)見的,當(dāng)然 使川低層api我們可以動態(tài)的創(chuàng)建線程,

10、也就不存在定長循環(huán)的問題。2. 對所要拆分線程的for語句,規(guī)定不得存在迭代相關(guān)性。因?yàn)閯?chuàng)建線程后線程之間足 獨(dú)立運(yùn)行的,如果線程之間存在相關(guān)性,將會使得程序產(chǎn)生混亂的運(yùn)行結(jié)果。當(dāng)然使用底層 的apt我們可以更杏效的控制和操作各個(gè)線程的合作與運(yùn)行,但是在openmp就無法實(shí)現(xiàn)了。 如果要進(jìn)行多線程化的循環(huán)出現(xiàn)了迭代相關(guān)性,那我們必須東新設(shè)計(jì)for循環(huán),以等效的無 相關(guān)性的循環(huán)代替它,倂是代價(jià)就是提高了程序的復(fù)雜性。3. 數(shù)據(jù)競爭。我們必須保證,各個(gè)線程之間不會對同一個(gè)外部或公共變鱟進(jìn)行操作(哪 怕是讀操作都是危險(xiǎn)的),在此情況下,intel提供/兩種方案:一種是盡可能的使用私冇 或局部變量;一

11、種是獲取公共變量的副木。總之,openmp的編程技術(shù)確實(shí)是非常的方便與美妙,只要我們在程序設(shè)計(jì)的吋候遵守 了以上幾個(gè)法則即可。當(dāng)然,openmp的功能耍遠(yuǎn)為強(qiáng)大的多,包括更s雜的線程分配方案、 更復(fù)雜的操作等,但是卻能很簡單的應(yīng)用。不過對木例來說還用不著那些技術(shù),僅pragma omp parallel for就足亦。k面我將這次試驗(yàn)的源代碼完整的貼上米,以使各位能夠更全 面的來了解-下程序的結(jié)構(gòu):/多線程試驗(yàn)程序include "stdafx. h"#include<stdio. h>#includc<omp. h>#include<coni

12、o.h>#define num 100void cout(int p) /s雜運(yùn)算函數(shù),僅是讓他做雜計(jì)筒; p=(1+2+3+4+5+6+7+8+9+10)/(9*8*7*6*5*4*3*2*1); for(int k=0;k<10000;k+);int main(int argc, char木 argv)int knum;char c=, 0 ;printf ("請選擇想執(zhí)行的程序:nl.單線程示例程序2.多線程示例程序43.退出n注:這兩段程序相同所不同的是第二段為多線程程序,計(jì)算性能成從電腦提示程序己經(jīng)開始 時(shí)計(jì)算! vi請輸入:k/這個(gè)for是整個(gè)循環(huán)主題了,也就

13、是程序的框架;但是這個(gè)for不是最耗性能的,所以不 用多線程化;for(;c!=3 ;)/如果c=3的話就直接退出,但是首次運(yùn)行時(shí)賦值為0,所以不會退出;/選擇輸入;/這個(gè)if就是第一段程序的總體了,可以與下個(gè)else ifc=_getch 0; if(c= f)比較發(fā)現(xiàn)僅少了 #pragma omp parallel for語句;printfcln第一段程序已經(jīng)開始了,該段程序是單線程程序“");for ( int j = 0; j < num; j+ )for (int p=0;p<10000;p+) cout (p); /開始做無用功!既進(jìn)行很人的 for循環(huán),乂調(diào)

14、用函數(shù),主要目的就是讓它耗吋間;for (int i=0; inum; i+)/順序輸出 0-99;printf ("%d ,ki);printf (n第一段程序已經(jīng)結(jié)束n請輸入:);else if(c= 2*)/第二段主程序;printf ("2n第二段程序己經(jīng)開始了,該段程序和第一段程序相同,只足多 tpragma omp parallel for,我們可以仔細(xì)觀察它們的區(qū)別11");#pragma. omp parallel for/就多/這么一句,在我的hi腦匕就快丫 75%;for ( int j = 0; j < num; j+ )kj=j;for(int p=0;p<1

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論