C中多线程的矩阵乘法

时间:2015-10-19 22:11:31

标签: c multithreading matrix-multiplication


我想创建一个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

我相信代码背后的逻辑是正确的,这肯定看起来像一个简单的参数传递问题。我把整个代码放在一边,因为如果我收到你对这个问题的评论,我会很高兴,也可以为你想要的工作提供更好的解决方案。 谢谢。

2 个答案:

答案 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;
}