我希望使用线程进行矩阵乘法,其中每个线程执行单个乘法,然后主线程将所有结果相加并将它们放在最终矩阵中的适当位置(在其他线程之后)退出)。
我尝试这样做的方法是创建一个包含每个线程结果的单行数组。然后我将遍历数组并添加+将结果放在最终矩阵中。
例如:如果你有矩阵:
A = [{1,4},{2,5},{3,6}] B = [{8,7,6},{5,4,3}]
然后我想要一个持有[8,20,7,16,6,12,16等]的数组 然后我会循环遍历数组,每2个数字加起来并将它们放在我的最终数组中。
这是一个硬件分配,所以我不是在寻找确切的代码,而是关于如何正确地将结果存储在数组中的一些逻辑。我正在努力跟踪如何跟踪每个矩阵中的位置,这样我就不会错过任何数字。
感谢。
EDIT2:忘记提到每个乘法都必须有一个线程。上面例子的含义是,每个都有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/
答案 0 :(得分: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);
然而,真正的工作需要在thr_rowcrunch(void * parm)中完成,它接收行数据,然后每个线程只是知道它自己的线程号。你在那个调度线程中所做的事情的胆量,但我只能猜测。
只是想在这里提供帮助,不确定这是否清楚。
答案 1 :(得分:0)
您需要存储M * K * N
个元素产品。这个想法大概是所有线程都将并行运行,或者至少能够运行,因此每个线程都需要自己的适当类型的不同存储位置。一种简单的方法是创建一个包含这么多元素的数组,但是元素类型是什么?
每个线程不仅需要知道将结果存储在哪里,还需要知道执行哪个乘法。所有这些信息都需要通过类型为void *
的单个参数来传达。然后,通常将创建一个适合于保存一个线程所需的所有数据的结构类型,为每个线程创建该结构类型的实例,然后将指针传递给那些结构。听起来好像您想要一个结构数组。
可以采用多种方法来处理细节,但对我来说,最自然的方法是为两个因素指定结构成员,并为产品存储一个成员。然后,我将让主线程声明此类结构的3D数组(如果所需的总数很小),否则将动态分配一个。例如,
struct multiplication {
// written by the main thread; read by the compute thread:
int factor1;
int factor2;
// written by the compute thread; read by the main thread:
int product;
} partial_result[M][K][N];
如何围绕该代码编写代码,这是预期的练习。