矩阵乘法 使用 win32 线程

Matrix Multiplication Using win32 threads

本文关键字:win32 线程 使用      更新时间:2023-10-16

我不知道我的代码出了什么问题......它始终在所有元素中返回零。提示问题在哪里会很棒:)

#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include <windows.h>
using namespace std;
int nGlobalCount = 0;
int thread_index = 0;
int num_of_thr=5;
int a[4][4], b[4][4], c[4][4];
int i, j, k;
struct v {
    int i; /*row*/
    int j; /*column*/
};
DWORD ThreadProc (LPVOID lpdwThreadParam ) {
    //
    struct v *input = (struct v *)lpdwThreadParam;
    int avg=4*4/num_of_thr;
    int count=0;
    for(int i = 0; i <= 3 ; i++) {
        for(int j = 0; j <= 3; j++) {
            int sum=0;
            for ( k = 0 ; k <= 3; k++) {
               sum=sum+((a[input->i][k])*(b[k][input->j]));
                c[input->i][input->j]=sum;
                count++;
            }
        }
    }
    //Print Thread Number
    //printf ("Thread #: %dn", *((int*)lpdwThreadParam));
    //Reduce the count
    return 0;
}
int main() {
    //    int x=0;
    cout<<"enter no of threads : ";
    cin>>num_of_thr;
    DWORD ThreadIds[num_of_thr];
    HANDLE ThreadHandles[num_of_thr];
    //struct v {
    //    int i; /*row*/
    //    int j; /*column*/
    //};
    struct v data[num_of_thr];
    int i , j , k;
    for ( int i = 0 ; i <= 3; i++) {
        for (int j = 0 ; j <= 3 ; j++) {
            a[i][j] = rand() % 10;
            b[i][j] = rand() % 10;
            c[i][j] = 0;
        }
    }
    for(int i = 0; i < num_of_thr/2; i++) {
        for(int j = 0; j < num_of_thr/2; j++) {
            data[thread_index].i = i;
            data[thread_index].j = j;
            ThreadHandles[thread_index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, &data[thread_index], 0,&ThreadIds[thread_index]);
            thread_index++;
        }
    }
    WaitForMultipleObjects(num_of_thr, ThreadHandles, TRUE, INFINITE);
    cout<<"The resultant matrix is "<<endl;
    for ( i = 0 ; i < 4; i++) {
        for ( j = 0 ; j < 4 ; j++)
            cout<<c[i][j]<<" ";
        cout<<endl;
    }
    for (int i=0; i<num_of_thr; i++)
        CloseHandle(ThreadHandles[i]);
    return 0;
}

乍一看,循环中的 sum 声明看起来很粗略。

for(int i = 0; i <= 3 ; i++) {
    for(int j = 0; j <= 3; j++) {
        for ( k = 0 ; k <= 3; k++)
            {
            int sum=sum+((a[input->i][k])*(b[k][input->j])); // this declaration seems wrong
            c[input->i][input->j]=sum;
            count++;
            }
        }
    }

您重新声明每个内部循环 sum,有效地使其为 0。您可能希望将声明从赋值中向上移动一个或两个循环,具体取决于您要实现的目标。

您是否意识到您有两组单独的变量,分别名为 a、b 和 c?一个是函数main的本地,另一个是整个程序的静态。我怀疑这不是你的意图。尝试删除 main 的本地版本。

马丁

除了前面提到的其他问题外,我在闲聊时发现了一些事情:

  • 你在用什么编译这个?在 VC++ 2010 中,它"工作",因为它输出非零,尽管它抱怨数组大小非常量DWORD ThreadIds[num_of_thr];数组声明(我只是num_of_thr常量并注释掉cin以快速测试它)。
  • 您是否确定使用 cin >> num_of_thr; 输入有效数量的线程 例如,如果num_of_thr为 0,这将解释零输出。这里有一个简单的cout num_of_thr会很有用。
  • 在以 for(int i = 0; i < num_of_thr/2; i++) { 开头的数据初始化循环中,您没有正确计算线程数,这将导致数组下溢或溢出。例如,如果num_of_thr为 5,则num_of_thr/2为 2,这导致仅初始化元素 0..3,而最后一个元素未初始化。数组下溢在技术上是可以的,尽管后面的CloseHandle()调用在尝试释放本质上随机的句柄时将失败。如果输入大量线程,则会溢出所有数组(例如,尝试使用 num_of_thr=10)。
  • 如果仍然不起作用,请尝试删除线程,以查看线程或代码本身是否是问题的根源。例如,可以在循环中手动调用 ThreadProc() 函数,而不是从线程中调用。使用调试器跟踪程序或将日志输出到 stdout/file(这也适用于线程模型)。
  • 而不是随机源矩阵,我会首先使用一些固定值,并获得已知结果。这样可以更轻松地确定代码是否实际计算了正确的结果。