我正在尝试使用C中的多个线程实现矩阵乘法,我想让用户决定矩阵的大小。 我的代码:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void printAMatrix(int, int, int*);
void* rowMulti(void*);
int r1, c1;
int r2, c2;
int* mtx1;
int* mtx2;
int* res;
int* resM;
int main(int argc, char** argv) {
printf("Input size of matrix 1:\n");
scanf("%d %d", &r1, &c1);
printf("Input size of matrix 2:\n");
scanf("%d %d", &r2, &c2);
if (c1 != r2) {
printf("These two matrice cannot do matrix multiplication!\n");
return -1;
}
mtx1 = (int*)calloc(r1 * c1, sizeof(int));
mtx2 = (int*)calloc(r2 * c2, sizeof(int));
int i, j, k;
printf("Input matrix 1:\n");
for (i=0; i< r1*c1; ++i) {
scanf("%d", mtx1 + i);
}
printf("Input matrix 2:\n");
for (i=0; i< r2*c2; ++i) {
scanf("%d", mtx2 + i);
}
printf("Size of matrice:\n%d %d\n%d %d\n", r1, c1, r2, c2);
printf("Matrix 1:\n");
printAMatrix(r1, c1, mtx1);
printf("Matrix 2:\n");
printAMatrix(r2, c2, mtx2);
res = (int*)calloc(r1*c2, sizeof(int));
//Single thread
for (i=0; i<r1; ++i) {
for (j=0; j<c2; ++j) {
int ele = 0;
for (k=0; k<c1; ++k) {
ele += *(mtx1 + c1*i+k) * *(mtx2 + c2*k+j);
}
*(res + c2*i + j) = ele;
}
}
printf("Product of the 2 matrices:\n");
printAMatrix(r1, c2, res);
resM = (int*)calloc(r1*c2, sizeof(int));
pthread_t* calThreads = (pthread_t*)calloc(r1, sizeof(pthread_t));
for (i=0; i<r1; ++i) {
if (pthread_create(calThreads+i, NULL, rowMulti, (void*)&i)) {
perror("pthread_create: ");
exit(1);
}
}
for (i=0; i<r1; ++i) {
if (pthread_join(*(calThreads+i), NULL)) {
perror("pthread_join: ");
exit(1);
}
}
printf("Product of the 2 matrices(Para):\n");
printAMatrix(r1, c2, resM);
free(mtx1);
free(mtx2);
free(res);
free(resM);
free(calThreads);
return 0;
}
void* rowMulti(void* rowNum) {
int row = *(int*)rowNum;
int j, k;
for (j=0; j<c2; ++j) {
int ele = 0;
for (k=0; k<c1; ++k) {
ele += *(mtx1 + c1 * row + k) * *(mtx2 + c2*k + j);
}
*(resM + c2*row + j) = ele;
}
printf("Row num: %d\n", row);
pthread_exit(NULL);
}
void printAMatrix(int r, int c, int* mtx) {
int i, j;
for (i=0; i<r; ++i) {
for (j=0; j<c; ++j) {
printf("%d ", mtx[c*i + j]);
}
printf("\n");
}
printf("\n");
}
例如,如果矩阵1中有4行,则应生成4个线程; 0应该传递给线程0中的启动例程,1应该传递给线程1中的启动例程,依此类推。但是,线程的启动例程没有得到我期望的参数。可以将1传递给多于1个启动例程,然后我可能在结果矩阵中丢失一行。一个例子:
Input size of matrix 1:
4 3
Input size of matrix 2:
3 5
Input matrix 1:
0 1 2 3 4 5 6 7 8 9 10 11
Input matrix 2:
8 7 6 5 4 3 2 1 0 1 2 3 4 5 6
Size of matrice:
4 3
3 5
Matrix 1:
0 1 2
3 4 5
6 7 8
9 10 11
Matrix 2:
8 7 6 5 4
3 2 1 0 1
2 3 4 5 6
Product of the 2 matrices:
7 8 9 10 13
46 44 42 40 46
85 80 75 70 79
124 116 108 100 112
Row num: 2
Row num: 1
Row num: 1
Row num: 3
Product of the 2 matrices(Para):
0 0 0 0 0
46 44 42 40 46
85 80 75 70 79
124 116 108 100 112
此处不计算第0行。任何人都知道如何解决它?
答案 0 :(得分:0)
我的想法是为第一个矩阵的每一行创建一个线程。
(线程同步,为了清晰起见而简单易用)
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void printAMatrix(int, int, int*);
typedef struct{
int row; // thread row
int mx2_r,mx2_c; // size of second matrix;
int *mtx1, // first matrix
*mtx2, // second matrix
*mtx3; // results matrix
}THREAD_PARAM;
void ThreadCompute(pthread_t *thd, int r, int mx2_r,int mx2_c, int *mtx1, int *mtx2, int *mtx3);
int main(int argc, char** argv) {
int r1, c1;
int r2, c2;
int* mtx1;
int* mtx2;
int* res;
int* resM;
int i, j, k;
printf("Input size of matrix 1:\n");
scanf("%d %d", &r1, &c1);
printf("Input size of matrix 2:\n");
scanf("%d %d", &r2, &c2);
if (c1 != r2) {
printf("These two matrice cannot do matrix multiplication!\n");
return -1;
}
mtx1 = calloc(r1 * c1, sizeof(int));
mtx2 = calloc(r2 * c2, sizeof(int));
printf("Input matrix 1:\n");
for (i=0; i< r1*c1; ++i) {
scanf("%d", mtx1 + i);
}
printf("Input matrix 2:\n");
for (i=0; i< r2*c2; ++i) {
scanf("%d", mtx2 + i);
}
printf("Size of matrice:\n%d %d\n%d %d\n", r1, c1, r2, c2);
printf("Matrix 1:\n");
printAMatrix(r1, c1, mtx1);
printf("Matrix 2:\n");
printAMatrix(r2, c2, mtx2);
res = calloc(r1*c2, sizeof(int));
//Single thread
for (i=0; i<r1; ++i) {
for (j=0; j<c2; ++j) {
int ele = 0;
for (k=0; k<c1; ++k) {
ele += *(mtx1 + c1*i+k) * *(mtx2 + c2*k+j);
}
*(res + c2*i + j) = ele;
}
}
printf("Product of the 2 matrices:\n");
printAMatrix(r1, c2, res);
resM = calloc(r1*c2, sizeof(int));
pthread_t* calThreads = calloc(r1, sizeof(pthread_t));
for (i=0; i<r1; ++i) {
ThreadCompute(calThreads+i, i, r2,c2,mtx1,mtx2,resM);
}
for (i=0; i<r1; ++i) {
if (pthread_join(*(calThreads+i), NULL)) {
perror("pthread_join: ");
exit(1);
}
}
printf("Product of the 2 matrices(Para):\n");
printAMatrix(r1, c2, resM);
free(mtx1);
free(mtx2);
free(res);
free(resM);
free(calThreads);
return 0;
}
void *Thread_ThreadCompute(void *data){
int i = (( THREAD_PARAM* ) data)->row;
int c1 = (( THREAD_PARAM* ) data)->mx2_r;
int c2 = (( THREAD_PARAM* ) data)->mx2_c;
int *mtx1 = (( THREAD_PARAM* ) data)->mtx1,
*mtx2 = (( THREAD_PARAM* ) data)->mtx2,
*res = (( THREAD_PARAM* ) data)->mtx3;
int j;
int k;
free(data);
for (j=0; j<c2; ++j) {
int ele = 0;
for (k=0; k<c1; ++k) {
ele += *(mtx1 + c1*i+k) * *(mtx2 + c2*k+j);
}
*(res + c2*i + j) = ele;
}
pthread_exit(NULL);
}
void ThreadCompute(pthread_t *thd, int r, int mx2_r,int mx2_c, int *mtx1, int *mtx2, int *mtx3){
THREAD_PARAM *param=malloc(sizeof(THREAD_PARAM));
param->row = r;
param->mx2_r = mx2_r;
param->mx2_c = mx2_c;
param->mtx1 = mtx1;
param->mtx2 = mtx2;
param->mtx3 = mtx3;
if (pthread_create(thd, NULL, Thread_ThreadCompute, (void*)param)) {
perror("pthread_create: ");
exit(1);
}
return ;
}
void printAMatrix(int r, int c, int* mtx) {
int i, j;
for (i=0; i<r; ++i) {
for (j=0; j<c; ++j) {
printf("%d ", mtx[c*i + j]);
}
printf("\n");
}
printf("\n");
}