#include #include #include #include #define NB_THREADS 4 struct map { int width; int height; double **cur_values; double **next_values; pthread_barrier_t barrier; }; void swap_values(struct map* m) { double ** tmp = m->next_values; m->next_values = m->cur_values; m->cur_values = tmp; } void compute_next_value(struct map* m, int i, int j) { m->next_values[i][j] = (m->cur_values[i-1][j] + m->cur_values[i+1][j] + m->cur_values[i][j-1] + m->cur_values[i][j+1] + m->cur_values[i][j]) / 5; } void compute_next_values(struct map* m) { for(int i=1; iheight-1; i++) { for(int j=1; jwidth-1; j++) { compute_next_value(m, i, j); } } swap_values(m); } void print_color(double v) { printf("\x1b[0m"); // reset colors if(v >= 10) printf("\x1b[41m"); // red background else if(v > 1) printf("\x1b[43m"); // yellow background else if(v < -10) printf("\x1b[44m"); // blue background else if(v < -1) printf("\x1b[46m"); // cyan background printf("%3.2d ", (int) v); printf("\x1b[0m"); // reset colors } void clear_screen() { printf("\e[1;1H\e[2J"); } void print_map(struct map* m) { clear_screen(); for(int i=0; iheight; i++) { for(int j=0; jwidth; j++) { print_color(m->cur_values[i][j]); } printf("\n"); } } void heat_random_point(struct map* m) { int i = 0; int j = 0; while(i==0 || i >= m->height-1) { i = rand() % m->height; } while(j==0 || j >= m->width-1) { j = rand() % m->width; } m->cur_values[i][j] = 99; if(rand()%2) // randomly add cold points m->cur_values[i][j] = -m->cur_values[i][j]; } void init_map(struct map* m, int height, int width, int nb_heat_points) { m->width = width; m->height = height; m->cur_values = malloc(sizeof(double*) * height); m->next_values = malloc(sizeof(double*) * height); for(int i=0; icur_values[i] = malloc(sizeof(double) * width); m->next_values[i] = malloc(sizeof(double) * width); for(int j=0; jcur_values[i][j] = 0; m->next_values[i][j] = 0; } } for(int i = 0; ii_start, param->i_stop); for(int i=0; initer; i++) { for(int i = param->i_start; i <= param->i_stop; i++) { for(int j=1; jmap->width; j++) { compute_next_value(param->map, i, j); } } pthread_barrier_wait(¶m->map->barrier); } return NULL; } int main(int argc, char**argv) { int world_height = 4096; int world_width = 4096; int nb_heat_points = 10; int niter = 50; srand(time(NULL)); struct map m; init_map(&m, world_height, world_width, nb_heat_points); pthread_barrier_init(&m.barrier, NULL, NB_THREADS+1); struct thread_param params[NB_THREADS]; pthread_t tids[NB_THREADS]; int i_start = 1; int i_stop = 0; struct timespec t1, t2; clock_gettime(CLOCK_MONOTONIC, &t1); for(int i=0; i world_height-2) i_stop = world_height-2; params[i].map = &m; params[i].i_start = i_start; params[i].i_stop = i_stop; params[i].niter = niter; pthread_create(&tids[i], NULL, worker, ¶ms[i]); } for(int i=0; i