使用win32线程的矩阵乘法
Posted
技术标签:
【中文标题】使用win32线程的矩阵乘法【英文标题】:Matrix Multiplication Using win32 threads 【发布时间】:2011-05-20 01:28:35 【问题描述】:我不知道我的代码出了什么问题……它总是在所有元素中返回零。提示问题出在哪里会很好:)
#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 #: %d\n", *((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;
【问题讨论】:
【参考方案1】:一目了然,循环中的 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。您可能希望将声明从分配中向上移动一到两个循环,具体取决于您要实现的目标。
【讨论】:
【参考方案2】:您是否意识到您有两组独立的变量,分别命名为 a、b 和 c?一个是函数 main 的局部变量,另一个是整个程序的静态变量。我怀疑这不是你想要的。尝试删除 main 本地的那个。
马丁
【讨论】:
@Loka :您是否在编辑后尝试过运行代码?这可能是您问题的根源。【参考方案3】:除了前面提到的其他问题之外,我在探索时发现了一些事情:
你用什么编译这个?使用 VC++ 2010 它“工作”,因为它输出非零,尽管它抱怨DWORD ThreadIds[num_of_thr];
数组声明具有非常量数组大小(我刚刚将 num_of_thr
设为常量并将 cin
注释掉快速测试)。
您确定输入的线程数是有效的cin >> num_of_thr;
例如,如果num_of_thr
为0,这将解释零输出。在这里为num_of_thr
提供一个简单的cout
会很有用。
在以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()
函数,而不是从线程中调用。使用调试器跟踪程序或将日志输出到标准输出/文件(这也适用于线程模型)。
首先我会使用一些固定值而不是随机源矩阵,但结果已知。这将更容易确定代码是否实际计算了正确的结果。
【讨论】:
感谢它适用于 9 个线程(即每个线程对一个元素进行操作),但对于更少的线程仍然无效。我想我应该像你说的那样重做初始化循环:) .. 谢谢以上是关于使用win32线程的矩阵乘法的主要内容,如果未能解决你的问题,请参考以下文章