pthread多线程棋盘划分法实现矩阵转置
棋盘法:
将整个矩阵抽象为多个同样大小的块。假设处理器的个数为p,编号为0,1,…,p-1,则将n阶矩阵分成p个大小为m*m个子块,p个子块组成一个的子块阵列。note:就是这里一定是划分成thread_num个相同的小矩阵切记,有大小不一的矩阵的话会出现问题的
代码如下
//
// matrix.c
// matrix
// 棋盘划分法
// Created by Yibin on 2021/4/4.
// Copyright © 2021 Yibin. All rights reserved.
//
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int **matrix;//矩阵
int **tmp;
int thread_num,dimension_num;//线程个数,矩阵维数
void init(){
matrix = (int **)malloc(dimension_num * sizeof(int *));
tmp = (int **)malloc(dimension_num * sizeof(int *));
for(int i=0;i<dimension_num;i++){
matrix[i] = (int *)malloc(dimension_num * sizeof(int));
tmp[i] = (int *)malloc(dimension_num * sizeof(int));
}
//如果想自己赋值,下面这个可以忽略
/*
FILE *fp = fopen("your own date.txt","r");
if(!fp){
printf("error");
exit(1);
}
else
{
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
fscanf(fp,"%d ",&(first[i][j]));
ans[i][j] = first[i][j];
}
}
fclose(fp);
}
*/
int cnt = 0;
for(int i=0;i<dimension_num;i++){
for(int j=0;j<dimension_num;j++){
matrix[i][j] = tmp[i][j] = cnt;
cnt++;
}
}
}
void *thread_function(void *arg){
//因为已经在主函数里确定了线程及维数的正确性所以这里可以直接计算而不用进行判断
int rank = *(int *)arg;
int u = rank / sqrt((double)thread_num);
int v = rank % (int)sqrt((double)thread_num);
//直接计算
int m = sqrt((double)(dimension_num*dimension_num/thread_num));
for(int i=u*m;i<(u+1)*m;i++){
for(int j=v*m;j<(v+1)*m;j++){
matrix[i][j] = tmp[j][i];
}
}
return NULL;
}
void print(int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main(int argc, const char * argv[]) {
dimension_num = atoi(argv[1]);
thread_num = atoi(argv[2]);
if(dimension_num*dimension_num % thread_num != 0)
fprintf(stderr,"format error");
init();
int x[thread_num];
pthread_t thread[thread_num];
for(int i=0;i<thread_num;i++){
x[i] = i;
pthread_create(&thread[i], NULL, thread_function, &x[i]);
}
for(int i=0;i<thread_num;i++){
pthread_join(thread[i], NULL);
}
print(dimension_num);
free(matrix);
free(tmp);
exit(0);
}
这个实验我一开始卡在了如果大小不规范应该如何解决,结果一直没有想到解决的方法,这让我有一点点的崩溃后来还是完成了