書接上文,我們提到了串行算法的矩陣轉置
接下來我們來看一看如何用並行程序來對矩陣進行轉置,想法有兩個,這裏先介紹第一種,塊棋盤劃分法。
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
好了,這樣我們就完成了對矩陣的轉置了。
希望大家不吝賜教,共同進步。