並行計算多線程塊棋盤劃分法實現矩陣轉置

書接上文,我們提到了串行算法的矩陣轉置
接下來我們來看一看如何用並行程序來對矩陣進行轉置,想法有兩個,這裏先介紹第一種,塊棋盤劃分法。
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

好了,這樣我們就完成了對矩陣的轉置了。
希望大家不吝賜教,共同進步。

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