1. 程式人生 > WINDOWS開發 >使用Windows API 編寫按行分配的計算矩陣向量相乘的並行程式

使用Windows API 編寫按行分配的計算矩陣向量相乘的並行程式

  水了一學期的院選修,萬萬沒想到期末考試還有比較硬核的程式設計題,居然還涉及到多執行緒了,而且是呼叫Windows介面函式寫多執行緒。雖然學彙編的時候有所瞭解,但畢竟沒嘗試過,思來想去,寫出了下面的蹩腳程式碼,不足之處還望各位批評指正。題目描述如下:

  採用windows介面函式,編寫一個計算矩陣向量相乘的並行程式,矩陣按行劃分後分別散發到不同的執行緒中,向量被複制到各個執行緒中,程式執行結束時,由主執行緒輸出結果向量。假設矩陣定義為浮點型陣列A[64][64],向量定義為浮點型陣列y[64],結果向量存放到浮點型陣列z[64]中,所用處理器有8個計算核。

  開始分析:如果把矩陣按行分配給不同執行緒的話,很明顯每個執行緒應該被分配八行。由於對不同行的矩陣進行操作不會發生衝突,所以連執行緒的同步機制都用不到,就是簡單的編寫一個計算矩陣向量相乘的執行緒函式,然後建立多個執行緒執行就可以了。程式碼實現如下

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 double z[64];    //結果向量 
 5 double y[64];    //待乘向量 
 6 double A[64][64];//待乘矩陣 
 7 const int numThreads = 8;//執行緒數
 8 
 9 DWORD WINAPI threadFunction(LPVOID pArg) {
10     int myNum = *((int *)pArg); //獲取本執行緒所需引數
11     int n = myNum + 8;             //
設定外層迴圈上界 12 for(int i = myNum; i < n; ++i){//相乘計算的具體步驟 13 for(int j = 0; j < 64; ++j) 14 z[i] += A[i][j] * y[i]; 15 } 16 return 0; 17 } 18 19 int main() { 20 HANDLE threadHandles[numThreads];//執行緒陣列 21 int tNum[numThreads];//用於傳給執行緒的引數陣列 22 23 printf("
請輸入矩陣:\n"); 24 for(int i = 0; i < 64; ++i) 25 for(int j = 0; j < 64; ++j) 26 scanf("%lf",&A[i][j]); 27 28 printf("請輸入向量:\n"); 29 for(int i = 0; i < 64; ++i) 30 scanf("%lf",&y[i]); 31 32 printf("相乘後的結果向量為: \n"); 33 34 for(int i = 0; i < numThreads; ++i) { 35 tNum[i] = i * 8; //給傳給執行緒的引數賦值 36 threadHandles[i] = CreateThread( NULL,// 安全屬性 37 0,// 棧大小 38 threadFunction,// 傳給執行緒的函式 39 (LPVOID)&tNum[i],// 傳給執行緒的引數 40 0,// 執行緒建立後立即啟用 41 NULL); // 新執行緒的id會被傳給這個引數所在的變數 42 } 43 WaitForMultipleObjects( numThreads,// 等待的執行緒數 44 threadHandles,// 等待的執行緒陣列 45 TRUE,// 等待所有訊號量有效在往下執行 46 INFINITE); // 表示無窮等待 47 for(int i = 0; i < 64; ++i) //輸出結果向量 48 printf("%.2lf ",z[i]); 49 return 0; 50 }

  至此,已經解決問題了。還好題目要求不是特別難,也算是通過一段程式碼初步瞭解如何使用Windows介面函式編寫多執行緒了。不得不說C語言確實強大,可惜我基礎不紮實加上現在又忘得差不多了,寫這段程式碼時居然想通過scanf("%f",&變數名來輸入double型別的值,遲遲得不到預期結果。我還以為是多執行緒惹的禍,得虧除錯了一下才知道原來我連值都沒有正確輸進去,double型別的輸入格式必須是%lf,輸出的話%f%lf均可,學到了學到了。只有犯錯了才能學的更透徹啊??