并行计算多线程块棋盘划分法实现矩阵转置

书接上文,我们提到了串行算法的矩阵转置
接下来我们来看一看如何用并行程序来对矩阵进行转置,想法有两个,这里先介绍第一种,块棋盘划分法。
Q:那么什么是块棋盘划分法呢?
A:yo~ yo~你看这个矩阵他又长又宽,就像这个棋盘他又大又方
(吴亦凡先生因言语激烈被踢出聊天室)
说实话这个yoyo让我想起了藤原书记。。。
在这里插入图片描述
没错,我们想想,这n*n的矩阵,确实是像个棋盘,那我们想到了,可以把他拆分成一个一个子块,然后子块之间先转换,然后子块内部自己再转置,这岂不是妙哉?!
那么我们一起来看看程序吧!

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "unistd.h"
int **matrix;//矩阵
int **tmp;
int T,n;//线程个数,矩阵维数
void init(){
    matrix = (int **)malloc(n * sizeof(int *));
    tmp = (int **)malloc(n * sizeof(int *));
    for(int i=0;i<n;i++){
        matrix[i] = (int *)malloc(n * sizeof(int));
        tmp[i] = (int *)malloc(n * sizeof(int));
    }
    //如果想自己赋值,下面这个可以忽略
    int cnt = 0;
    for(int i=0;i<n;i++){
    	for(int j=0;j<n;j++){
    		matrix[i][j] = tmp[i][j] = cnt;
    		cnt++;
		}
	}
}

void *thread_function(void *arg){
    int rank = *(int *)arg;
    int u = rank / sqrt((double)T);
    int v = rank % (int)sqrt((double)T);
    //这里我偷了个懒,直接一起进行子块转换与内部转置
    int m = sqrt((double)(n*n/T));
    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 free(int n){
	free(matrix);
}

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[]) {
    n = 10;//atoi(argv[1]);
	T = 4;//atoi(argv[2]);
	init();
	int x[T];
	pthread_t thread[T];
	for(int i=0;i<T;i++){
	    x[i] = i;
	    pthread_create(&thread[i], NULL, thread_function, &x[i]);
	}
	for(int i=0;i<T;i++){
	    pthread_join(thread[i], NULL);
	}
	print(n);
    return 0;
}

结果如下,

0 10 20 30 40 50 60 70 80 90
1 11 21 31 41 51 61 71 81 91
2 12 22 32 42 52 62 72 82 92
3 13 23 33 43 53 63 73 83 93
4 14 24 34 44 54 64 74 84 94
5 15 25 35 45 55 65 75 85 95
6 16 26 36 46 56 66 76 86 96
7 17 27 37 47 57 67 77 87 97
8 18 28 38 48 58 68 78 88 98
9 19 29 39 49 59 69 79 89 99

好了,这样我们就完成了对矩阵的转置了。
希望大家不吝赐教,共同进步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章