【发布时间】:2020-06-25 15:51:33
【问题描述】:
您好,我尝试通过以下练习自学多线程:将两个硬编码矩阵矩阵 1 和矩阵 2 相乘,并将结果保存在矩阵 3 中。策略是分配一个线程来计算结果矩阵(matrix3)中的每个元素。
虽然程序是可以运行的,但是结果是不对的。任何启示为什么结果是错误的?谢谢!
代码
#include <stdio.h>
#include <stdlib.h>
#include "thread.h"
void *multiply(void *arguments);
#define X 2
#define Y 2
#define Z 3
int matrix1[X][Y] = {{0, 1}, {2, 3}};
int matrix2[Y][Z] = {{4, 5, 6}, {7, 8, 9}};
int matrix3[X][Z];
struct arguments_combo
{
int rowIdxInMatrix1;
int colIdxInMatrix2;
};
int main()
{
thread_t threads[X * Z];
for (int rowIdx = 0; rowIdx < X; rowIdx++)
{
for (int colIdx = 0; colIdx < Z; colIdx++)
{
struct arguments_combo arguments;
arguments.rowIdxInMatrix1 = rowIdx;
arguments.colIdxInMatrix2 = colIdx;
pthread_create(&(threads[rowIdx * Z + colIdx]), NULL, multiply, (void *)&arguments);
}
}
for (int rowIdx = 0; rowIdx < X; rowIdx++)
{
for (int colIdx = 0; colIdx < Z; colIdx++)
{
void *val_ptr;
pthread_join(threads[rowIdx * Z + colIdx], &val_ptr);
int *cur_val_ptr = (int *)val_ptr;
printf("The rowIdx: %d and colIdx: %d and the val: %d\n", rowIdx, colIdx, *cur_val_ptr);
matrix3[rowIdx][colIdx] = *cur_val_ptr;
free(cur_val_ptr);
}
}
return 0;
}
void *multiply(void *arguments)
{
struct arguments_combo *data_ptr = (struct arguments_combo *)arguments;
int rowIdxInMatrix1 = data_ptr->rowIdxInMatrix1;
int colIdxInMatrix2 = data_ptr->colIdxInMatrix2;
int *sum = malloc(sizeof(int));
for (int i = 0; i < Y; i++)
{
*sum += matrix1[rowIdxInMatrix1][i] * matrix2[i][colIdxInMatrix2];
}
pthread_exit((void *)sum);
return NULL;
}
输出
The rowIdx: 0 and colIdx: 0 and the val: 9
The rowIdx: 0 and colIdx: 1 and the val: 29
The rowIdx: 0 and colIdx: 2 and the val: 29
The rowIdx: 1 and colIdx: 0 and the val: 34
The rowIdx: 1 and colIdx: 1 and the val: 39
The rowIdx: 1 and colIdx: 2 and the val: 39
【问题讨论】:
-
也许一开始就去掉线程,直到你有一个工作的串行版本。然后将其转换为线程版本。 “过早的优化是万恶之源”。
-
顺便说一句,为什么要使用 void *?你不应该使用类型系统来帮助你吗?
-
我认为 Strassen mutrix 乘法算法已经到位。您可以使用该算法来降低时间复杂度。它基于并行处理。
-
这里使用多线程的重点只是为了练习而不是优化矩阵乘法效率。但是,是的,我喜欢这句话“过早的优化是万恶之源”:)。无论如何,谢谢你们的cmets!
标签: c multithreading