多核多線程技術(shù)WINAPI_實(shí)驗(yàn)報(bào)告_第1頁(yè)
多核多線程技術(shù)WINAPI_實(shí)驗(yàn)報(bào)告_第2頁(yè)
多核多線程技術(shù)WINAPI_實(shí)驗(yàn)報(bào)告_第3頁(yè)
多核多線程技術(shù)WINAPI_實(shí)驗(yàn)報(bào)告_第4頁(yè)
多核多線程技術(shù)WINAPI_實(shí)驗(yàn)報(bào)告_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、實(shí)驗(yàn)一 :Windows*Threads多線程編程模塊一:基礎(chǔ)練習(xí)4編譯執(zhí)行,輸出結(jié)果:HelloThread 1HelloThread 3HelloThread 0HelloThread 2簡(jiǎn)答與思考:1 寫出修改后的HelloThreads的代碼。關(guān)鍵代碼:(已用黃色標(biāo)記)/ HelloWorld.cpp :定義控制臺(tái)應(yīng)用程序的入口點(diǎn).#include stdafx.h#include const int numThreads=4;DWORD WINAPI helloFunc(LPVOID arg)int myNum=*(int *)arg);printf( HelloThread %dn

2、 ,myNum);return 0;int _tmain( int argc, _TCHAR* argv口)HANDLE hThreadnumThreads;int tNumnumThreads;for (int i=0;inumThreads;i+) tNumi=i;hThreadi=CreateThread(NULL,0,helloFunc,&tNumi,0,NULL);WaitForMultipleObjects(numThreads,hThread, true INFINITE);return 0;2實(shí)驗(yàn)總結(jié)在主程序中循環(huán)調(diào)用CreateThread()函數(shù)生成四個(gè)子線程分別去執(zhí)行he

3、lloFunc()函數(shù),并將線程的句柄保存在hTread數(shù)組中,CreateThread()的第四個(gè)參數(shù)給每個(gè)線程傳遞參數(shù)tNum獲取該線程號(hào),由helloFunc()的參數(shù)接收- 1 -并指向內(nèi)容。由于主線程為每個(gè)子線程傳遞了不同的參數(shù),所以通過子線程的 執(zhí)行結(jié)果可以判斷出四個(gè)線程的執(zhí)行順序。這個(gè)實(shí)驗(yàn)要我們初步認(rèn)識(shí)到了程序 的并行化設(shè)計(jì)思想,為以后的并行化程序設(shè)計(jì)打下了基礎(chǔ)。- 3 -模塊二:臨界區(qū)實(shí)驗(yàn)3 審行程序編譯執(zhí)行,Pi的值為:Pi = 3.141592654The time to calculate PI was 0.327000 seconds6并行程序編譯執(zhí)行,Pi的值為:PI

4、 = 3.1419305356The time to calculate PI was 0.063000 seconds簡(jiǎn)答與思考:1如何進(jìn)行并行化的?請(qǐng)寫出并行化的思路與具體的代碼。本例中用兩個(gè)線程協(xié)同工作,分別計(jì)算局部的sum1然后累加到全局變量sum 中,由于多線程多sum變量的修改會(huì)引起數(shù)據(jù)競(jìng)爭(zhēng),因此在這里采用了臨界區(qū)方 法,將對(duì)sum的更新操作定義為臨界區(qū)操作。依據(jù)剛獲得的本線程序號(hào),以步進(jìn) 長(zhǎng)度numthreads (線程總數(shù))間隔地累加求和,好比線程0求和第0、2、4、6、8塊,線程1求和第1、3、5、7、9塊。這是為保證兩個(gè)線程負(fù)載平衡。for(int i=myNum;inum

5、_steps;i+=numthreads)x=(i+0.5)*step;multhread+=4.0/(1.0+x*x);這部分在多線程并行部分之外,是由單線程執(zhí)行的,作用是將前述各個(gè)線程 獨(dú)立間隔求和的結(jié)果匯總,得到完整的和,也就是數(shù)值積分結(jié)果。關(guān)鍵代碼:(已用黃色標(biāo)記)/ CriticalSectionPi.cpp :定義控制臺(tái)應(yīng)用程序的入口點(diǎn)#include stdafx.h#include #include const int numthreads=2;static long num_steps=10000000;double step=0.0;double pi=0.0,sum=0.

6、0;CRITICAL_SECTION cs;DWORD WINAPI Func(LPVOID arg)(int myNum=*(int *)arg);double sum1=1.0,x;for (int i=myNum;inum_steps;i+=numthreads)x=(i+0.5)*step;sum1+=4.0/(1.0+x*x);EnterCriticalSection(&cs);sum+=sum1;LeaveCriticalSection(&cs);return 0;int _tmain( int argc, _TCHAR* argv口)clock_t start,stop;star

7、t=clock();HANDLE hthreadnumthreads;int tNumnumthreads;InitializeCriticalSection(&cs);step=1.0/( double )num_steps;for (int i=0;inumthreads;+i)tNumi=i;hthreadi=CreateThread(NULL,0,Func,&tNumi,0,NULL);WaitForMultipleObjects(numthreads,hthread, true INFINITE);DeleteCriticalSection(&cs);pi=step*sum;stop

8、=clock();printf( Pi=%12.9fn ,pi);printf( The time of calculation was %0.12f secondsn ,( double )(stop-start)/1000.0); return 0;2在本實(shí)驗(yàn)中,哪些變量是需要保護(hù)的?采取什么方法實(shí)現(xiàn)的?將suml累加到sum中,sum是臨界區(qū)代碼,需要保護(hù),因?yàn)槠涫且饠?shù)據(jù) 競(jìng)爭(zhēng)的關(guān)鍵;采用把其設(shè)置成為臨界區(qū)代碼的方法實(shí)現(xiàn)。EnterCriticalSection(&cs);sum+=sum1;LeaveCriticalSection(&cs);3是否可以對(duì)該并行化方案進(jìn)行進(jìn)一步的優(yōu)化?

9、如何優(yōu)化?暫時(shí)沒想到其他進(jìn)一步優(yōu)化方案。- 5 -4 實(shí)驗(yàn)總結(jié)并行程序相對(duì)于串行程序的加速比為5.1904, 相比之下并行效率提高了2.6倍,這是我們想要的結(jié)果,并行的確是提高了計(jì)算的速度,所以對(duì)于這種大數(shù)據(jù)累加的問題對(duì)算法的優(yōu)化是必要的。- 6 -模塊三:事件實(shí)驗(yàn)3 編譯執(zhí)行,Result is 0.69314218The time of calculation was 21.544000 seconds4閱讀代碼,回答下面問題。(1)主線程共創(chuàng)建 5個(gè)子線程。(2)各子線程調(diào)用的函數(shù)各是什么?DWORD WINAPI threadProc(LPVOID par)DWORD WINAPI m

10、asterThreadProc(LPVOID par)(3)主線程等待5個(gè)子線程的執(zhí)行結(jié)束。6 改進(jìn)后的,編譯執(zhí)行,Result is 0.69314218The time of calculation was 15.807000 seconds簡(jiǎn)答與思考:1在WINAPI threadProc(LPVOID par)函數(shù)中為什么用臨界區(qū)互斥了線程對(duì) threadCoun的訪問?為什么對(duì)于全局?jǐn)?shù)據(jù)變量 sumsfl勺訪問沒有互斥?WINAPI threadProc(LPVOID par)。函數(shù)使用多線程執(zhí)行的 threadCount是記錄線程個(gè)數(shù)的,而它對(duì)于masterThreadProc()

11、函數(shù)要等待所有線程 (threadCount)做完對(duì)sums的計(jì)算,然后再進(jìn)行最后的四個(gè)線程結(jié)構(gòu)的累加,它 是這兩個(gè)函數(shù)的共享變量,對(duì)于它的操作必須原子化,以保證每次只有一個(gè)線 程對(duì)其自增,所以使用臨界區(qū)互斥了每個(gè)線程對(duì)threadCount的訪問,避免了數(shù)據(jù)沖突的發(fā)生。而對(duì)于數(shù)據(jù)變量sums每一個(gè)數(shù)組元素下標(biāo)值是每個(gè)子線程獲得的參數(shù),該 參數(shù)標(biāo)記了各個(gè)子線程,sums數(shù)組分別對(duì)應(yīng)一個(gè)線程,從而使每個(gè)子線程操作 的變量分別保存在對(duì)應(yīng)的數(shù)組元素中,四個(gè)線程互不影響,所以并不需要互斥。2簡(jiǎn)述源代碼中存在的問題,詳述提出的改進(jìn)方案及相關(guān)代碼。源代碼中為使“ master”子線程等待其余四個(gè)子線程執(zhí)行

12、完畢,使用空循 環(huán)保持“master”子進(jìn)程的“等待”狀態(tài),這顯然不是好的方法;改進(jìn)方案中使 用了事件,事件用于線條線程間的執(zhí)行順序以保證對(duì)共享資源操作的完整性, 本程序中,“master”子線程是另外創(chuàng)建的,它需要另外四個(gè)子線程的執(zhí)行結(jié)果, 所以需要等待以保證獲得它們的結(jié)果后再進(jìn)行操作,使用事件機(jī)制,程序中定 義四個(gè)未激發(fā)的人工重置事件,“master”子進(jìn)程在執(zhí)行時(shí)以wait方式等待事件 被激發(fā),由于其余四個(gè)子線程在完成任務(wù)后將事件從未激發(fā)態(tài)設(shè)置為激發(fā)態(tài), 從而使“master”子線程繼續(xù)執(zhí)行余下操作。關(guān)鍵代碼:(以用黃色標(biāo)記)/ ThreadEvent.cpp :定義控制臺(tái)應(yīng)用程序的入口

13、點(diǎn)/麥凱特爾對(duì)數(shù)級(jí)數(shù)估算ln(1+x),(-1x=1) 的值#include stdafx.h#include #include #include #include #define NUMTHREADS 4#define SERIES_MEMBER_COUNT 100000HANDLE *threadHandles,masterThreadHandle,*eventHandles;CRITICAL_SECTION countCS;double *sums;double x = 1.0, res = 0.0;int threadCount = 0;double getMember( int n,

14、 double x)double numerator = 1;for ( int i=0; in; i+ ) numerator = numerator*x;if ( n % 2 = 0 )return ( - numerator / n );else return numerator/n;DWORD WINAPI threadProc(LPVOID par)int threadindex = *( int *)par);sumsthreadIndex = 0;for (int i=threadindex; iSERIES_MEMBER_COUNT;i+=NUMTHREADS) sumsthr

15、eadindex += getMember(i+1, x);SetEvent(eventHandlesthreadIndex);/EnterCriticalSection(&countCS);/threadCount+;/LeaveCriticalSection(&countCS);delete par;return 0;DWORD WINAPI masterThreadProc(LPVOID par)for ( int i=0; iNUMTHREADS; i+ )ResumeThread(threadHandlesi);/ Start computing threads/while (thr

16、eadCount!= NUMTHREADS)/ busy wait until all threads are done with computation of partial sums/WaitForMultipleObjects(NUMTHREADS,eventHandles,TRUE,INFINITE);res = 0;for (int i=0; iNUMTHREADS; i+)res += sumsi;return 0;int _tmain( int argc, _TCHAR* argv口)clock_t start, stop;threadHandles = newHANDLENUM

17、THREADS + 1;eventHandles = new HANDLENUMTHREADS + 1;/InitializeCriticalSection(&countCS);sums = new double NUMTHREADS;start = clock();for (int i=0; iNUMTHREADS;i+) int * threadIdPtr = new int ;*threadIdPtr = i;threadHandlesi = CreateThread(NULL, 0, threadProc, threadIdPtr, CREATE_SUSPENDED, NULL);ev

18、entHandlesi = CreateEvent(NULL,TRUE,FALSE,NULL);threadHandlesNUMTHREADS = CreateThread(NULL, 0, masterThreadProc,NULL, 0, NULL);printf( Count of ln(1 + x) Mercators series members is %dn,SERIES_MEMBER_COUNT);printf( Argument value of x is %fn, ( double )x);WaitForMultipleObjects(NUMTHREADS+1,threadH

19、andles,TRUE,INFINITE);stop = clock();for (int i=0; iNUMTHREADS+1; i+ )CloseHandle(threadHandlesi);delete threadHandles;delete eventHandles;/DeleteCriticalSection(&countCS);delete sums;printf( Result is %10.8fn, res);printf( By function call ln(1 + %f) = %10.8fn,x, log(1+x);printf( The time of calcul

20、ation was %f secondsn ,( double )(stop - start)/1000.0);printf( Press any key . );getch();return 0;3 是否可以對(duì)該并行化方案進(jìn)行進(jìn)一步的優(yōu)化?如何優(yōu)化?線程在被創(chuàng)建時(shí)就執(zhí)行,不用再去喚醒, master”只需等待事件被激發(fā), 效率會(huì)有所提高。4 實(shí)驗(yàn)總結(jié)- 10 -模塊四:信號(hào)量實(shí)驗(yàn)3 確定串行版本項(xiàng)目為啟動(dòng)項(xiàng),編譯執(zhí)行。Total Words: 984719Total Even Words: _494315Total Odd Words: 4904044 確定并行版本項(xiàng)目為啟動(dòng)項(xiàng),編譯執(zhí)行。T

21、otal Words: _984719Total Even Words: _494306Total Odd Words: _4904049 修正后項(xiàng)目的輸出結(jié)果為:Total Words: 984719Total Even Words: _494315Total Odd Words: _490404簡(jiǎn)答與思考:1 Serial.cpp 與 Threaded.cpp 代碼執(zhí)行結(jié)果不一致的原因是什么?在多線程中fd 和 TotalWords , TotalEvenWords ,TotalOddWords 屬于共享變量,在并發(fā)執(zhí)行的過程中會(huì)造成數(shù)據(jù)沖突。fd對(duì)于每個(gè)線程是互斥的,是 因?yàn)樵谖募羔樛?/p>

22、下一行改變時(shí),不允許其他線程對(duì)該操作有影響,不然就會(huì)造 成 該 問 題 的 計(jì) 數(shù) 結(jié) 果 不 正 確 的 現(xiàn) 象 ; 而 TotalWords , TotalEvenWords ,TotalOddWords 這幾個(gè)變量,是計(jì)算總的字符串個(gè)數(shù),含有偶數(shù)數(shù)量字符的字符串的個(gè)數(shù)以及含有奇數(shù)數(shù)量字符的字符串的個(gè)數(shù)。毋庸置疑,它們也是共享資源,在對(duì)他們進(jìn)行累加時(shí),要注意數(shù)據(jù)沖突。2 如何修改Threaded.cpp 代碼?寫出修改思路和關(guān)鍵代碼。前面我們已經(jīng)學(xué)過了用臨界區(qū)可以對(duì)于共享資源進(jìn)行線程的互斥訪問,這個(gè)問題也可以采取臨界區(qū)去做,但是我們?cè)囍鴩L試另一種方法信號(hào)量。信號(hào)量也是一種內(nèi)核對(duì)象,它可以對(duì)

23、當(dāng)前資源計(jì)數(shù),這也是它與臨界區(qū)最大的不同,當(dāng)資源數(shù)量大于0時(shí),等待該信號(hào)量的線程就可以獲得該資源得以繼續(xù)執(zhí)行。本問題的改進(jìn)方案是:在代碼中應(yīng)用兩個(gè)信號(hào)量hSem1,hSem2, hSeml用于線程對(duì)文 件 指 針 fd 的 互 斥 , hSem2 則 是 用 于 對(duì) 全 局 變 量 TotalWords , TotalEvenWords ,TotalOddWords 的互斥。 對(duì)于每一個(gè)子線程,由于我們的思路是按行計(jì)算,然后累加的,對(duì)偶數(shù)數(shù)量字符的字符串的個(gè)數(shù)以及含有奇數(shù)數(shù)量字符的字符串的個(gè)數(shù)的計(jì)算,要注意采取巧妙點(diǎn)的處理辦法關(guān)鍵代碼:(已用黃色標(biāo)記)#include #include #in

24、clude FILE *fd;int TotalEvenWords = 0,TotalOddWords = 0,TotalWords = 0;HANDLE hSem1,hSem2;const int NUMTHREADS = 4;int GetNextLine(FILE *f, char *Line) if (fgets(Line, 132, f)=NULL) if (feof(f)return EOF;elsereturn 1; int GetWordAndLetterCount( char *Line)int Word_Count = 0,OddWords = 0,EvenWords =

25、0,Letter_Count = 0;for ( int i=0;i132;i+) if (Linei!= )&(Linei!=0)&(Linei!=n ) Letter_Count+;else if (Letter_Count!=0)if (Letter_Count % 2)OddWords+;Word_Count+;Letter_Count = 0;else EvenWords+;Word_Count+;Letter_Count = 0;if (Linei=0) break;return (Word_Count*10000+OddWords*100+EvenWords);DWORD WINAPI CountWords(LPVOID arg)BOOL bDone = FALSE ;char inLine132;int temp = 0;while (!bDone)WaitForSingleObject(hSem1,INFINITE);bDone = (GetNextLine(fd, inLine) = EOF);ReleaseSemaphore(hSem1

溫馨提示

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

評(píng)論

0/150

提交評(píng)論