大連東軟信息學(xué)院-多核多線程-試驗一_第1頁
大連東軟信息學(xué)院-多核多線程-試驗一_第2頁
大連東軟信息學(xué)院-多核多線程-試驗一_第3頁
大連東軟信息學(xué)院-多核多線程-試驗一_第4頁
大連東軟信息學(xué)院-多核多線程-試驗一_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、項目一 : Windows*Threads 多線程編程模塊一:基礎(chǔ)模塊4 編譯執(zhí)行, 輸出結(jié)果:簡答與思考:1 寫出修改后的 HelloThreads 的代碼。/ HelloThreads.cpp :定?義?控?制?臺?應(yīng)?| 用?程?序的?入?口2點?。?#include stdafx.h#include const int numThreads = 4;DWORD WINAPI helloFunc(LPVOID arg) int myNum=*( int *)arg);printf( Hello Thread!Thread %d n ,myNum); return 0;int main(

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

3、函數(shù),并將線程的句柄保存在 hThread 數(shù)組中, CreateThread() 的第四個參數(shù)給每 個線程傳遞參數(shù) tNum 獲取該線程號,由 helloFunc ()的參數(shù)接收并指向內(nèi)容。由于 主線程為每個子線程傳遞了不同的參數(shù), 所以通過子線程的執(zhí)行結(jié)果可以判斷出四個線 程的執(zhí)行順序。 這個實驗要我們初步認識了程序的并行化設(shè)計思想, 為以后的并行化程序設(shè)計打下了基礎(chǔ)。3 模塊二:臨界區(qū)模塊編譯執(zhí)行,編譯執(zhí)行,記錄結(jié)果:記錄結(jié)果:7 加速比: 1. , 并行效率: 0.47625988簡答與思考:1 如何進行并行化的?請寫出并行化的思路與具體的代碼。 答:在程序中創(chuàng)建兩個子線程,另主線程等

4、待所有的子線程執(zhí)行結(jié)束后退出。 代碼:#include stdafx.h#include #include static long num_steps=1000000000;const int gNumThreads=2;double step=0.0,pi=0.0,sum=0.0;CRITICAL_SECTION gCS;DWORD WINAPI threadFunction(LPVOID pArg)int myNum=*( int *)pArg); double sum1=0.0,x;for ( int i=myNum; i num_steps; i+=gNumThreads) x = (

5、i+0.5)*step;sum1 = sum1 + 4.0/(1.0 + x*x);EnterCriticalSection(&gCS);sum+=sum1;LeaveCriticalSection(&gCS);return 0;int main( int argc,_TCHAR* argv) clock_t start, stop;start = clock();HANDLE threadHandlesgNumThreads; int tNumgNumThreads;InitializeCriticalSection(&gCS);step = 1.0/(double ) num_steps;

6、for ( int i=0;igNumThreads;+i)tNumi=i; threadHandlesi=CreateThread(NULL,0,threadFunction,&tNumi,0,NULL);WaitForMultipleObjects(gNumThreads,threadHandles,TRUE,INFINITE);DeleteCriticalSection(&gCS);pi = step * sum;stop = clock();printf(Pi = %12.12fn ,pi);printf(The time of calculation was %f secondsn,

7、( double )(stop - start)/1000.0);return 0;4 在本模塊中,哪些變量是需要保護的?為什么?采取什么方法實現(xiàn)的?答:1)臨界資源是需要保護的,也就是 sum 變量,這里將對 sum 的更新操作定義為臨 界區(qū)操作2)在多線程程序中,對于在子線程執(zhí)行的代碼中出現(xiàn)的被更新的全局變量要多加考慮,因 為具有這種特點的變量,很有可能會引起數(shù)據(jù)沖突,如果處理不好會使程序產(chǎn)生功能性錯誤3)EnterCriticalSection(&gCS);sum+=sum1;LeaveCriticalSection(&gCS);在創(chuàng)建子線程前調(diào)用 InitializeCriticalS

8、ection(&gCS); 函數(shù)對臨界區(qū)進行初始化,然 后 調(diào) 用 EnterCriticalSection(&gCS);函 數(shù) 獲 取 臨 界 區(qū) 的 訪 問 權(quán) , 訪 問 結(jié) 束 后 調(diào) 用LeaveCriticalSection(&gCS);函 數(shù) 釋 放 臨 界 區(qū) 的 訪 問 權(quán) , 在 退 出 程 序 前 需 要 調(diào) 用DeleteCriticalSection(&gCS); 函數(shù)注銷臨界區(qū),釋放臨界區(qū)資源。3 是否可以對該并行化方案進行進一步的優(yōu)化?如何優(yōu)化? 答:可以。更改創(chuàng)建線程的數(shù)目,分別計算出加速比和效率,比較結(jié)果進行取舍。4 項目總結(jié)。 在使用臨界區(qū)時,可以根據(jù)需要,

9、在程序中定義多個臨界區(qū)對象,用來對不同的代碼段進行互斥訪問,這樣做的好處是可以增加程序的并行度。總之,在設(shè)計多線程程序時, 應(yīng)該為每一個需要互斥的共享資源定義一個臨界區(qū)變量。模塊三:事件模塊3 編譯執(zhí)行,記錄結(jié)果:seconds4 閱讀代碼,回答下面問題。(1) 主線程共創(chuàng)建5 個子線程。(2) 各子線程調(diào)用的函數(shù)各是什么?DWORD WINAPI threadProc(LPVOID par)DWORD WINAPI masterThreadProc(LPVOID par)(3) 主線程等待4 個子線程的執(zhí)行結(jié)束。6 改進后的,編譯執(zhí)行,記錄結(jié)果:Result issecondsThe tim

10、e of calculation was簡答與思考:1 在 WINAPI threadProc(LPVOID par) 函數(shù)中為什么用臨界區(qū)互斥了線程對 threadCount 的 訪問?為什么對于全局數(shù)據(jù)變量 sums的訪問沒有互斥?WINAPI threadProc(LPVOID par) 函數(shù)使用多線程執(zhí)行的 threadCount 是記錄線程個 數(shù)的,而它對于 masterThreadProc ()函數(shù)要等待所有線程( threadCount )做完對 sums 的計算,然后再進行最后的四個線程結(jié)構(gòu)的累加,它是這兩個函數(shù)的共享變量,對于它的 操作必須原子化,以保證每次只有一個線程對其自

11、增,所以使用臨界區(qū)互斥了每個線程對 threadCount 的訪問,避免了數(shù)據(jù)沖突的發(fā)生。而對于數(shù)據(jù)變量 sums每一個數(shù)組元素下標(biāo)值是每個子線程獲得的參數(shù), 該參數(shù)標(biāo)記了各 個子線程, sums數(shù)組分別對應(yīng)每一個線程,從而使每個子線程操作的變量分別保存在對應(yīng) 的數(shù)組元素中,四個線程互不影響,所以并不需要互斥。2 簡述源代碼中存在的問題,詳述提出的改進方案及相關(guān)代碼。源代碼中為使 “master ”子線程等待其余四個子線程執(zhí)行完畢,使用空循環(huán)保持 “ master ”子線程的“等待”狀態(tài),這顯然不是好的方法;改進方案中使用了事件,事件用于線程間 的執(zhí)行順序以保證對共享資源操作的完整性,本程序中

12、,“ master ”子線程是另外創(chuàng)建的, 它需要另外四個子線程的執(zhí)行結(jié)果,所以需要等待以保證獲得它們的結(jié)果后再進行操作, 使用事件機制,程序中定義四個未激發(fā)的人工重置事件,“master ”子進程在執(zhí)行時以 wait方式等待事件被激發(fā),由于其余四個子線程在完成任務(wù)后將事件從未激發(fā)設(shè)置為激發(fā)態(tài), 從而使“ master ”子線程繼續(xù)執(zhí)行余下操作#include stdafx.h#include #include #include #include #define NUMTHREADS 4#define SERIES_MEMBER_COUNT 100000HANDLE *threadHandle

13、s, masterThreadHandle,*eventHandles; CRITICAL_SECTION countCS;double *sums;double x = 1.0, res = 0.0;int threadCount = 0;double getMember( int n, double x)double numerator = 1;for ( int i=0; in; i+ ) numerator = numerator*x;if ( n % 2 = 0 )return ( - numerator / n );elsereturn numerator/n;DWORD WINA

14、PI threadProc(LPVOID par)int threadIndex = *( int *)par); sumsthreadIndex = 0;for ( int i=threadIndex; iSERIES_MEMBER_COUNT;i+=NUMTHREADS) sumsthreadIndex += getMember(i+1, x);SetEvent(eventHandlesthreadIndex);/Signal Master thread that one more processing thread is done /EnterCriticalSection(&count

15、CS);/threadCount+; /LeaveCriticalSection(&countCS);delete par;return 0;DWORD WINAPI masterThreadProc(LPVOID par)for ( int i=0; iNUMTHREADS; i+) ResumeThread(threadHandlesi); / Start computing threads/while (threadCount != NUMTHREADS) / busy wait until all threads are done with computation of partial

16、 sumsWaitForMultipleObjects(NUMTHREADS,eventHandles,TRUE,INFINITE);res = 0;for ( int i=0; iNUMTHREADS; i+)res += sumsi;return 0;int main()clock_t start,stop;threadHandles = new HANDLENUMTHREADS + 1; eventHandles = new HANDLENUMTHREADS +1 ;/InitializeCriticalSection(&countCS);sums = new double NUMTHR

17、EADS; start=clock();for ( int i=0; iNUMTHREADS;i+)int * threadIdPtr =new int ;*threadIdPtr = i;threadHandlesi = CreateThread(NULL, 0, threadProc, threadIdPtr, CREATE_SUSPENDED, NULL);eventHandlesi=CreateEvent(NULL,TRUE,FALSE,NULL);threadHandlesNUMTHREADS = CreateThread(NULL, 0, masterThreadProc, NUL

18、L, 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,threadHandles,TRUE,INFINITE); stop=clock();for ( int i=0; iNUMTHREADS+1; i+ ) CloseHandle(threadHandlesi);delete threadHand

19、les;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 calculation was %f secondsn,( double )(stop-start)/1000.0);printf( Press any key . );getch();return 0;3 是否可以對該并行化方案進行進一

20、步的優(yōu)化?如何優(yōu)化? 線程在被創(chuàng)建時就執(zhí)行,不再去喚醒, “master ”只需等待事件被激發(fā),效率就會有所 提高。4 項目總結(jié)。模塊四:信號量模塊3 這是串行代碼實現(xiàn),編譯執(zhí)行,記錄結(jié)果。6 編譯執(zhí)行并行版本,多次運行,記錄結(jié)果: 第 1 次執(zhí)行結(jié)果:第 2 次執(zhí)行結(jié)果:第 3 次執(zhí)行結(jié)果:10 修正后項目的輸出結(jié)果為:簡答與思考:1 SemaphoreS 項目與 SemaphoreT 項目執(zhí)行結(jié)果不一致的原因是什么?在多線程中 fd 和 TotalWords , TotalEventWords , TotalOddWords 屬于共享變量,在 并發(fā)執(zhí)行的過程中會造成數(shù)據(jù)沖突。 fd 對于每

21、個線程是互斥的,是因為在文件指針往下一 行改變時,不準(zhǔn)許其它線程對該操作有影響,不然就會造成該問題的計數(shù)結(jié)果不正確的現(xiàn) 象;而 TotalWords , TotalEventWords ,TotalOddWords 這幾個變量,是計算總的字符串 個數(shù),含有偶數(shù)數(shù)量字符的字符串的個數(shù)及含有奇數(shù)個字符的字符串的個數(shù),毋庸置疑, 它們也是共享資源,在對他們進行累加時,要注意數(shù)據(jù)沖突。2 如何修改 SemaphoreT 項目源代碼?寫出修改思路和關(guān)鍵代碼。可以采用臨界區(qū)的方法去做,也可以采用信號量。信號量也是一種內(nèi)核對象,它可以 對當(dāng)前的資源計數(shù),這是與臨界區(qū)最大的不同,當(dāng)資源數(shù)量大于 0 時,等待該

22、信號量的線 程就可以獲得該資源得以繼續(xù)執(zhí)行。改進方案:在代碼中應(yīng)用兩個信號量hSem1, hSem2, hSem1 用于線程對文件指針 fd的互斥, hSem2 用于對全局變量 TotalWords ,TotalEventWords ,TotalOddWords 的互斥, 對于每一個子線程,由于我們的思路是按行計算,然后累加的,對于偶數(shù)數(shù)量字符的字符 串的個數(shù)以及含有奇數(shù)數(shù)量字符串的個數(shù)計算,要注意采取巧妙點的處理辦法。#include stdafx.h#include #include #include FILE *fd;int TotalEvenWords = 0, TotalOddWor

23、ds = 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; else return 1;int GetWordAndLetterCount( char *Line) int Word_Count = 0,OddWords=0,EvenWords=0, Letter_Count = 0; for ( int i=0;i132;i+)if (Li

24、nei!= )&(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 lCount=0;while (!bDone) WaitForSingleObject(hSem1,INFINITE);/ 進 ?bDone = (GetNextLine(fd, inLine) = EOF);ReleaseSemaphore(hSem1,1,NULL); / 出 ?if

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論