gpt4 book ai didi

c - 在 C 中使用多线程的矩阵乘法

转载 作者:行者123 更新时间:2023-11-30 17:06:30 25 4
gpt4 key购买 nike

我正在尝试使用 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 可能会传递到多个启动例程,然后我可能会在结果矩阵中丢失一行。一个例子:

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 行。有谁知道怎么解决吗?

最佳答案

我的想法是为第一个矩阵的每一行创建一个线程。

(线程同步,为了清晰和简单起见,跳过)

#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");
}

关于c - 在 C 中使用多线程的矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34646215/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com