简介
细胞自动机(又称元胞自动机),名字虽然很深奥,但是它的行为却是非常美妙的。所有这些怎样实现的呢?我们可以把计算机中的宇宙想象成是一堆方格子构成的封闭空间,尺寸为N的空间就有NN个格子。而每一个格子都可以看成是一个生命体,每个生命都有生和死两种状态,如果该格子生就显示蓝色,死则显示白色。每一个格子旁边都有邻居格子存在,如果我们把33的9个格子构成的正方形看成一个基本单位的话,那么这个正方形中心的格子的邻居就是它旁边的8个格子。
每个格子的生死遵循下面的原则:
1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。
2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)
实现思路
将全局矩阵分解为大小相等的(工作)块,这样我们就可以实现生命的游戏。
初始化:从文件中读取数据:一个包含游戏初始状态的m×n矩阵。
为了与其他处理器通信,我设置了一个局部矩阵和一个全局矩阵。局部矩阵是一种混合状态。对于处理器0,它可以从局部矩阵中获得全局矩阵。
MPI并行实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
#include <stdio.h> #include <string.h> #include "mpi.h" #include <stdlib.h> static int MAX_M; static int MAX_N; static int epoch; static int DEAD=0; static int ALIVE=1; double exe_time; int size, myid, s, ver, row, col, dir; int *local_matrix = NULL; int *tmpmatrix = NULL; int *global_matrix = NULL; int *newglobal_matrix = NULL; MPI_Request requests[4]; MPI_Status status[4]; FILE * matrix; void display(int *local_matrix){ int i, j; printf("%10c", ' '); printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); for (i = 0; i < MAX_M; i++){ printf("\n%10c", ' '); for (j = 0; j < MAX_N; j++) if (local_matrix[i * MAX_N + j] == ALIVE) printf("+"); else printf("-"); } printf("\n%10c\n", ' '); } int adj8(int neighbor, int row, int col){ int res; if(neighbor == 2){ return local_matrix[row * MAX_N + col]; }else if(neighbor == 3){ return ALIVE; }else{ return DEAD; } } int main(int argc,char *argv[]){ MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &myid); ver = MAX_M / size; epoch= atoi(argv[1]); MAX_M= atoi(argv[2]); MAX_N= atoi(argv[3]); local_matrix = (int*)malloc(sizeof(int) * (ver+2) * MAX_N); tmpmatrix = (int*)malloc(sizeof(int) * (ver+2) * MAX_N); for (row = 0; row < ver+2; row++) { for (col = 0; col < MAX_N; col++) { local_matrix[row*MAX_N+col] = DEAD; tmpmatrix[row*MAX_N+col] = DEAD; } } //Initialization if (myid == 0) { int i; global_matrix = (int*)malloc(sizeof(int) * MAX_M * MAX_N); newglobal_matrix = (int*)malloc(sizeof(int) * MAX_M * MAX_N); if((matrix = fopen("matrix.txt","r"))==NULL){ printf("the file can not open."); return -1; } for(row = 0; row < MAX_M; row++){ for(col = 0; col < MAX_N; col++){ fscanf(matrix,"%d ", &global_matrix[row*MAX_N + col]); } fscanf(matrix,"\n"); } memcpy(&local_matrix[MAX_N], &global_matrix[0], ver * MAX_N * sizeof(int)); for (dir = 1; dir < size; dir++) { MPI_Send(&global_matrix[dir*ver*MAX_N], ver * MAX_N, MPI_INT, dir, 1, MPI_COMM_WORLD); } display(global_matrix); } else { //For each processor, there is a local matrix. MPI_Recv(&local_matrix[MAX_N], ver * MAX_N, MPI_INT, 0, 1, MPI_COMM_WORLD, status); } exe_time = -MPI_Wtime(); for (int count=0; count<epoch;count++){ int req_id = 0; if (myid == 0) { MPI_Isend(&local_matrix[(ver)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]); MPI_Irecv(&local_matrix[(ver+1)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]); printf("\n"); display(local_matrix); } else { MPI_Irecv(local_matrix, MAX_N, MPI_INT, myid - 1, 1, MPI_COMM_WORLD, &requests[req_id++]); MPI_Isend(&local_matrix[(ver)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]); MPI_Irecv(&local_matrix[(ver+1)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]); MPI_Isend(&local_matrix[MAX_N], MAX_N, MPI_INT, myid - 1, 1, MPI_COMM_WORLD, &requests[req_id++]); } MPI_Waitall(req_id, requests, status); for (row = 1; row < ver+1; row+=1){ for (col = 0; col < MAX_N; col++){ int neighbor = 0, c, r; for (r = row - 1; r <= row + 1; r++) for (c = col - 1; c <= col + 1; c++){ if (c < 0 || c >= MAX_N) continue; if (local_matrix[r * MAX_N + c] == ALIVE) neighbor++; } if (local_matrix[row * MAX_N + col] == ALIVE) neighbor--; tmpmatrix[row * MAX_N + col] = adj8(neighbor, row, col); } } for (row = 1; row < ver+1; row+=1){ for (col = 0; col < MAX_N; col++){ local_matrix[row * MAX_N + col] = tmpmatrix[row * MAX_N + col]; } } } if (myid == 0) { exe_time += MPI_Wtime(); printf("Time: %lf \n", exe_time); memcpy(global_matrix, &local_matrix[MAX_N], ver * MAX_N * sizeof(int)); for (dir = 1; dir < size; dir++) { MPI_Recv(&global_matrix[dir*ver*MAX_N], ver*MAX_N, MPI_INT, dir, 1, MPI_COMM_WORLD, status); } printf("Last Status:\n"); display(global_matrix); } else { MPI_Send(&local_matrix[MAX_N], ver * MAX_N, MPI_INT, 0, 1, MPI_COMM_WORLD); } MPI_Finalize(); return 0; } |
输出示例
你好,请问在这个文章里 windows 报错这个是变量没有声明吗?我成功运行过其他消息收发代码,但是这个代码里进程意外关闭。
https://blog.csdn.net/a1309602336/article/details/138399882?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22138399882%22%2C%22source%22%3A%22a1309602336%22%7D