我想创建一个C程序,通过使用线程计算两个N * N矩阵的乘法
我通过引用Matrix Multiplication using multiple threads来启动此代码,但是不是为结果矩阵的每个单元格创建N * N个线程,我想创建N个线程以同时进行乘法,其中将计算结果矩阵的每一行通过不同的线程。
到目前为止我的代码看起来像这样
.demo {
color: #777;
}
.demo:hover {
color: #333;
}
当我用
编译时#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#define N 2
struct v
{
int i;//Row
int j;//Column
};
int A[N][N]={{1,2},{3,4}};//Matrix 1
int B[N][N]={{2,3},{4,5}};//Matrix 2
int C[N][N];//Resulting Matrix
static void * fnc (void *arg)
{
struct v *data = (struct v *)arg;
int l;
for(l=0;l<N;l++)
{
int i=((struct v*)data[l]).i;//Row No
int j=((struct v*)data[l]).j;//Column No
int accumulator = 0;
int d,sum=0;
for (d = 0; d < N; d++)
{
sum = sum + A[i][d]*B[d][j];
}
C[i][j] = sum;
sum = 0;
}
return;
}
int main()
{
pthread_t threads[N];
int i,k;
for(i=0;i<N;i++)
{
struct v *data[N];
for(k=0;k<N;k++)
{
data[k]=(struct v *)malloc(sizeof(struct v));
data[k].i = i; //assign the row of C for thread to calculate
data[k].j = k; //assign the column of C for thread to calculate
}
//In this example it creates 2 threads with passing data.
//Data consists of row and column pairs for each thread, that will be calcuting the pairs.
//Consider first iteration of this loop:
//Thread 1 is created and data consists of (0,0) and (0,1) which are the targeted calculation cells for thread 1.
//In the second iteration: Thread 2 will have (1,0) and (1,1) pairs in its data.
pthread_create(&threads[i],NULL,fnc,data);
}
for(i=0; i < N; i++)
pthread_join(threads[i], NULL);
for (i = 0; i < N; i++)
for (k = 0; k < N; k++)
printf("%d\t", C[i][k]);
return 0;
}
我收到此错误:
gcc thread.c -lpthread -lrt
我相信代码背后的逻辑是正确的,这肯定看起来像一个简单的参数传递问题。我把整个代码放在一边,因为如果我收到你对这个问题的评论,我会很高兴,也可以为你想要的工作提供更好的解决方案。 谢谢。
答案 0 :(得分:0)
我已经使用3 * 3线程实现了3 * 3矩阵乘法。代码可以修改为N * N.代码是自解释的。
*header*/
#include <pthread.h>
#include <stdio.h>
#include<stdlib.h>
/*macro*/
#define NUM_THREADS 9
/*I have defined the structure here to pass the multiple arguments
when creating threads*/
/*structure declaration*/
struct thread_data
{
int element1[3];//passing the element of one matrix
int element2[3];//passing the element of other matrix
int sum;//storing the result of multiplication
}thread_data_array[NUM_THREADS];
/**
* @brief finds matrix multiplication function
* param [in] : accepts the thread arguments
*
* @return void pointer
*/
void *multiplication(void *threadarg)
{
int i;
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;/*type cast the
void pointer to the struct thread*/
//pointer
my_data->sum=0;
for(i=0;i<3;i++){/*multiply and add each element
of 1st matrix to 2nd matrix*/
my_data->sum=my_data->sum
+((my_data->element1[i])*(my_data->element2[i]));
}
}
/*main*/
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
int t;
int matrix_b[3][3]={{156,223,345},{456,5678,656},{712,811,922}};
//to store the matrix
int matrix_a[3][3]={{123,278,335},{437,547,656},{734,832,944}};
int ans[9];
int i,j,count,z,k,l,q;
t=i=j=z=count=k=q=l=0;
/*
suppose the matrices are
1 2 3 1 2 3
4 5 6 1 2 3
7 8 9 1 2 3
so to perform the multiplication
row 1 2 3 will be multiplied too column
111 222 333 respectively.
so 123 shold be stored in 3 spreate threads
and 111 222 333 should be stored in 3 seprate threads
123 111 should be in common thread
123 222 should be in common thread
123 333 should be in common thread
in this way below logic i have
writtten.
It is hard to understand at first glance..
so enjoy!!!!!!
*/
while(z<3){
for(count=0;count<3;count++){/*store the each row of
first matrix 3 times in 3 seprate threads*/
for(j=0;j<3;j++)
thread_data_array[t].element1[j]
= matrix_a[i][j];
t++;
}
/*store the each column of the second matrix in the spreate threads*/
for(k=0;k<3;k++){
for(l=0;l<3;l++)
thread_data_array[q].element2[l]
= matrix_b[l][k];
q++;
}
i++;
z++;
}
/*we have total 9 element in resultant matrix,so to create it we should
create 9 threads*/
for(t=0; t<NUM_THREADS; t++){
rc =pthread_create (&threads[t], NULL, multiplication,
(void *) &thread_data_array[t]);
/*we are passing the function pointer and
the pointer to structure as the argument,since we want to pass multiple argumen
ts we are passing the structure poi
nter as the arguments.*/
if (rc){//if rc is not 0,error is there
printf("ERROR; return code from () is %d\n", rc);
exit(-1);
}
}
/*
NAME
pthread_join - join with a terminated thread
SYNOPSIS
#include <pthread.h>
int pthread_join(pthread_t thread_here, void **retval);
Compile and link with -pthread.
DESCRIPTION
The pthread_join() function waits for the thread specified by thread_here
to terminate. If that thread has already terminated, then
pthread_join() returns immediately. The thread specified by thread
must be joinable.
*/
for (i = 0; i < 9; i++)/*to wait for all the threads to complete*/
pthread_join(threads[i], NULL);
printf("%d %d %d\n",thread_data_array[0].sum,thread_data_array[1].sum,thread_data_array[2].sum);
printf("%d %d %d\n",thread_data_array[3].sum,thread_data_array[4].sum,thread_data_array[5].sum);
printf("%d %d %d\n",thread_data_array[6].sum,thread_data_array[7].sum,thread_data_array[8].sum);
}
答案 1 :(得分:0)
这是一个由@Michi发布的工作解决方案。你的问题是你把一个带有相同地址的指针传递给pthread_create
,你也有一些内存分配问题。你必须为两个dimmentional数组分配内存,然后传入pthread_create
。
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#define N 3
#define n 3
struct v
{
size_t i;
size_t j;
};
double A[N][N] = {{1.0, 2.0, 4.0}, {3.0, 4.0, 5.0}, {4.0, 5.0, 7.0}};
double B[N][N] = {{2.0, 3.0, 9.0}, {4.0, 5.0, 7.0}, {2.0, 3.0, 9.0}};
double C[N][N];
static void * multiplication(void *arg){
struct v *data = (struct v *)arg;
size_t l;
for(l=0; l < N; l++)
{
size_t i=(data[l]).i;
size_t j=(data[l]).j;
double sum=0;
size_t d;
for (d = 0; d < N; d++)
{
sum = sum + A[i][d]*B[d][j];
}
C[i][j] = sum;
sum = 0;
}
return 0;
}
int main(void)
{
pthread_t threads[n];
size_t i, k;
struct v **data;
data = (struct v **)malloc(n * sizeof(struct v*));
for(i = 0; i < n; i++)
{
data[i] = (struct v *)malloc(n * sizeof(struct v));
for(k = 0; k < n; k++)
{
data[i][k].i = i;
data[i][k].j = k;
}
pthread_create(&threads[i], NULL, multiplication, data[i]);
}
for(i = 0; i < n; i++)
{
pthread_join(threads[i], NULL);
}
for (i = 0; i < N; i++)
{
for (k = 0; k < N; k++)
{
printf("%lf\t", C[i][k]);
}
printf("\n");
free(data[i]);
}
free(data);
return 0;
}