2013-03-16 41 views
5

我正在寻找使用线程进行矩阵乘法,其中每个线程执行一次乘法,然后主线程将所有结果相加,并将它们放在适当的位置在最后一个矩阵中出现(在其他线程退出后)。矩阵与线程相乘(每个线程都是单个乘法)

我试图做到这一点的方式是创建一个单行数组,其中包含每个线程的结果。然后我会遍历数组并将结果添加到最终矩阵中。

例如:如果你有矩阵:

A = [{1,4},{2,5},{3,6}] B = [{8,7,6},{ 5,4,3}]

然后,我想要一个数组[8,20,7,16,6,12,16等] 然后,我会遍历数组加起来,每2个数字并将它们放入我的最后阵列。

这是一个硬件指派,所以我不是在寻找确切的代码,而是关于如何正确地将结果存储在数组中的一些逻辑。我正在努力跟踪每个矩阵中的位置,以便我不会错过任何数字。

谢谢。编辑2:忘了提及必须有一个单一的线程进行每一个单一的乘法。对于上面的例子来说,将会有18个线程进行自己的计算。

编辑:我目前正在使用此代码作为基础工作。

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define M 3 
#define K 2 
#define N 3 
#define NUM_THREADS 10 

int A [M][K] = { {1,4}, {2,5}, {3,6} }; 
int B [K][N] = { {8,7,6}, {5,4,3} }; 
int C [M][N]; 

struct v { 
    int i; /* row */ 
    int j; /* column */ 
}; 

void *runner(void *param); /* the thread */ 

int main(int argc, char *argv[]) { 

    int i,j, count = 0; 
    for(i = 0; i < M; i++) { 
     for(j = 0; j < N; j++) { 
     //Assign a row and column for each thread 
     struct v *data = (struct v *) malloc(sizeof(struct v)); 
     data->i = i; 
     data->j = j; 
     /* Now create the thread passing it data as a parameter */ 
     pthread_t tid;  //Thread ID 
     pthread_attr_t attr; //Set of thread attributes 
     //Get the default attributes 
     pthread_attr_init(&attr); 
     //Create the thread 
     pthread_create(&tid,&attr,runner,data); 
     //Make sure the parent waits for all thread to complete 
     pthread_join(tid, NULL); 
     count++; 
     } 
    } 

    //Print out the resulting matrix 
    for(i = 0; i < M; i++) { 
     for(j = 0; j < N; j++) { 
     printf("%d ", C[i][j]); 
     } 
     printf("\n"); 
    } 
} 

//The thread will begin control in this function 
void *runner(void *param) { 
    struct v *data = param; // the structure that holds our data 
    int n, sum = 0; //the counter and sum 

    //Row multiplied by column 
    for(n = 0; n< K; n++){ 
     sum += A[data->i][n] * B[n][data->j]; 
    } 
    //assign the sum to its coordinate 
    C[data->i][data->j] = sum; 

    //Exit the thread 
    pthread_exit(0); 
} 

来源:您需要http://macboypro.wordpress.com/2009/05/20/matrix-multiplication-in-c-using-pthreads-on-linux/

+1

这已经完成了大约十万次。通过确定机器上的CPU核心数“C”,确定需要多少个行x列向量乘法,将后者除以前者(大致),然后将其发送到“ C'线程独立处理。任何模数(额外的矢量直到'C-1')都会作为额外的乘法被发送到第一组线程。您将很难获得更高效和简单的算法,特别是考虑到绝对不需要任何锁定。 – WhozCraig 2013-03-16 01:36:05

+0

对不起,我不清楚。根据这个任务,每个必须完成的乘法操作必须有一个线程。意思是,对于我给出的示例矩阵,将会有18个线程执行18次乘法。 这并不意味着高效。这只是一个硬件练习。 – Kinru 2013-03-16 01:40:03

+0

是的,我认为它只是一个练习。当你采取像A [500] [800]×B [800] [1000]'这样的概念时,这个概念会很快降低。当你可以完成乘法运算时,花费的时间越多,开始加入线程的时间就越多。呃,好吧。祝你好运! – WhozCraig 2013-03-16 01:47:10

回答

0

不知道山楂许多线程调度和我也不能肯定,如果你会用后来加盟来接他们。我猜你在C这里,所以我会用线程ID,以此来跟踪处理哪一行..是这样的:

#define NUM_THREADS 64 
/* 
* struct to pass parameters to a dispatched thread 
*/ 
typedef struct { 
    int value;  /* thread number */ 
    char somechar[128]; /* char data passed to thread */ 
    unsigned long ret; 
    struct foo *row; 
} thread_parm_t; 

如果我猜测每个线程都在拿起它的行数据具有一些定义类型foo的指针*行。一堆整数或花车,甚至复杂的类型。无论你需要传递给线程。

/* 
* the thread to actually crunch the row data 
*/ 
void *thr_rowcrunch(void *parm); 

pthread_t tid[NUM_THREADS]; /* POSIX array of thread IDs */ 

然后在你的主代码段是这样的:

thread_parm_t *parm=NULL; 

然后分派线程的东西,如:

for (i = 0; i < NUM_THREADS; i++) { 
    parm = malloc(sizeof(thread_parm_t)); 
    parm->value = i; 
    strcpy(parm->somechar, char_data_to-pass); 
    fill_in_row (parm->row, my_row_data); 
    pthread_create(&tid[i], NULL, thr_insert, (void *)parm); 
} 

再后来就:

for (i = 0; i < NUM_THREADS; i++) 
    pthread_join(tid[i], NULL); 

然而真正的工作需要t在thr_rowcrunch(void * parm)中接收行数据,然后每个线程只知道自己的线程号。你在那个调度线程中做什么的胆量,但我只能猜测。

只是试图帮助这里,不知道这是否清楚。

+0

你可以分享矩阵乘法的实际输入数据吗?我真的对这个问题感兴趣,即使只是出于我自己的原因。我想制定一个整洁的线程解决方案,非常有价值的方式来喝咖啡并编写解决方案。 – 2013-03-16 01:50:08

+0

实际输入数据是可变的。对于赋值,我们需要做一些文件I/O来读取矩阵,然后输出结果。与我的问题无关。由于代码不应该依赖于矩阵,所以我一直使用我在原始文章中给出的例子来尝试实现这个工作。 – Kinru 2013-03-16 01:51:42