【发布时间】:2016-01-07 02:03:05
【问题描述】:
我正在尝试使用 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 行。有人知道怎么解决吗?
【问题讨论】:
-
将同一个堆栈变量作为
pthread_create调用传递给多个arg的代码几乎不可避免地是错误的。每个线程在pthread_create调用之后的某个时间运行。没有对订购的保证。同时父线程正在改变i。在每个线程运行时,i的实际值不太可能与调用pthread_create时相同。您需要为每个pthread_create调用传递一个指向不同变量的 arg 指针。 -
致电 BLAS DGEMM 并完成它。强烈反对车轮改造。