sequential.c
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <sys/time.h> double time_diff(struct timeval t1, struct timeval t2) { double sec1, sec2; sec1 = t1.tv_sec + t1.tv_usec*1e-6; sec2 = t2.tv_sec + t2.tv_usec*1e-6; return sec2-sec1; } int build_house(int nx, int column, int site[]) { int num_sol = 0; bool is_sol; int i, j; // Try to build a house in each line of column for (i=0; i<nx; i++) { site[column] = i; // Check if this placement is still a solution is_sol = true; for (j=column-1; j>=0; j--) { if ((site[column] == site[j]) || (site[column] == site[j] - (column-j)) || (site[column] == site[j] + (column-j))) { is_sol = false; break; } } if (is_sol) { if (column == nx-1) { // If this is the last column, printout the solution num_sol += 1; } else { // The placement is not complete. // Try to place the house on the next column num_sol += build_house(nx, column+1, site); } } } return num_sol; } void main() { int num_sol; int nx=14; int *site; struct timeval start, end; printf("nx=%d\n", nx); site = (int*)malloc(nx*sizeof(int)); gettimeofday(&start, NULL); num_sol = build_house(nx, 0, site); gettimeofday(&end, NULL); printf("num_sol=%d\n", num_sol); printf("elapsed time=%.6lf sec\n", time_diff(start,end)); }
answer.c
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <sys/time.h> #include "mpi.h" #define GRANULARITY 5 // it should be less than nx #define MASTER 0 int nprocs, myrank; struct job { bool working; // true:working, false:quit int site[GRANULARITY]; }; struct job_msg { int solutions_found; int origin; }; double time_diff(struct timeval t1, struct timeval t2) { double sec1, sec2; sec1 = t1.tv_sec + t1.tv_usec*1e-6; sec2 = t2.tv_sec + t2.tv_usec*1e-6; return sec2-sec1; } int master_build_house(int nx, int column, int site[]) { int num_sol = 0; bool is_sol; int i, j; for (i=0; i<nx; i++) { // Try to build a house in each line of column site[column] = i; // Check if this placement is still a solution is_sol = true; for (j=column-1; j>=0; j--) { if ((site[column] == site[j]) || (site[column] == site[j] - (column-j)) || (site[column] == site[j] + (column-j))) { is_sol = false; break; } } if (is_sol) { if (column == GRANULARITY-1) { // If this is the last level (granularity of the job), // send a next job to a worker num_sol += send_job_worker(nx, site); } else { // The placement is not complete. // Try to place the house on the next column num_sol += master_build_house(nx, column+1, site); } } } return num_sol; } int worker_build_house(int nx, int column, int sub_site[]) { int num_sol = 0; bool is_sol; int i, j; // Try to build a house in each line of column for (i=0; i<nx; i++) { sub_site[column] = i; // Check if this placement is still a solution is_sol = true; for (j=column-1; j>=0; j--) { if ((sub_site[column] == sub_site[j]) || (sub_site[column] == sub_site[j] - (column-j)) || (sub_site[column] == sub_site[j] + (column-j))) { is_sol = false; break; } } if (is_sol) { if (column == nx-1) { // If this is the last column, printout the solution num_sol += 1; } else { // The placement is not complete. // Try to place the house on the next column num_sol += worker_build_house(nx, column+1, sub_site); } } } return num_sol; } int send_job_worker(int nx, int site[]) { int num_sol = 0; // The number of solutions found meanwhile int i; struct job todo; struct job_msg msg; // Set the job todo.working = true; for (i=0; i<GRANULARITY; i++) todo.site[i] = site[i]; // Recieve the last result from a worker MPI_Recv(&msg, sizeof(msg), MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); num_sol = msg.solutions_found; // Send the new job to the worker MPI_Send(&todo, sizeof(todo), MPI_BYTE, msg.origin, 0, MPI_COMM_WORLD); return num_sol; } int wait_remaining_results() { // Wait for remaining results, sending a quit whenever a new result arrives int num_sol = 0; int n_workers = nprocs-1; struct job todo; struct job_msg msg; todo.working = false; while (n_workers > 0) { // Receive a message from a worker MPI_Recv(&msg, sizeof(msg), MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); num_sol += msg.solutions_found; MPI_Send(&todo, sizeof(todo), MPI_BYTE, msg.origin, 0, MPI_COMM_WORLD); n_workers -= 1; } return num_sol; } void worker(int nx) { // There is a default message which lets a worker request a // job reporting the number of solutions found in the last iteration int num_sol; struct job_msg msg; msg.origin = myrank; msg.solutions_found = 0; // Request initial job MPI_Send(&msg, sizeof(msg), MPI_BYTE, MASTER, 0, MPI_COMM_WORLD); while (true) { // Wait for a job or a quit message struct job todo; MPI_Recv(&todo, sizeof(todo), MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if (todo.working == false) break; num_sol = worker_build_house(nx, GRANULARITY, todo.site); // Ask for more work msg.origin = myrank; msg.solutions_found = num_sol; MPI_Send(&msg, sizeof(msg), MPI_BYTE, MASTER, 0, MPI_COMM_WORLD); } } void main(int argc, char* argv[]) { int num_sol; int nx=14; int *site; struct timeval start, end; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); if (myrank == MASTER) { printf("nx=%d\n", nx); printf("nprocs=%d\n", nprocs); site = (int*)malloc(nx*sizeof(int)); gettimeofday(&start, NULL); num_sol = master_build_house(nx, 0, site); num_sol += wait_remaining_results(); gettimeofday(&end, NULL); printf("num_sol=%d\n", num_sol); printf("elapsed time=%.3lf sec\n", time_diff(start,end)); } else { worker(nx); } MPI_Finalize(); }
myparallel.c
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <sys/time.h> #include <mpi.h> #define THRES 5 #define READY_TAG 111 #define SITE_TAG 222 #define RSLT_TAG 333 #define WORK_TAG 444 #define READY_STATE -111 #define WRITING_STATE -222 #define WORK 1 #define FINISH 0 double time_diff(struct timeval t1, struct timeval t2) { double sec1, sec2; sec1 = t1.tv_sec + t1.tv_usec*1e-6; sec2 = t2.tv_sec + t2.tv_usec*1e-6; return sec2-sec1; } int operate_slave(int nx, int site[], int *rcnt){ int ready, totrslt = 0, rslt; int work = WORK; MPI_Status stat; while(1){ MPI_Recv(&ready, 1, MPI_INT, MPI_ANY_SOURCE, READY_TAG, MPI_COMM_WORLD, &stat); if(ready == READY_STATE){ MPI_Send(&work, 1, MPI_INT, stat.MPI_SOURCE, WORK_TAG, MPI_COMM_WORLD); MPI_Send(site, THRES, MPI_INT, stat.MPI_SOURCE, SITE_TAG, MPI_COMM_WORLD); break; } else{ MPI_Recv(&rslt, 1, MPI_INT, stat.MPI_SOURCE, RSLT_TAG, MPI_COMM_WORLD, &stat); *rcnt += 1; totrslt += rslt; } } return totrslt; } int slave_build_house(int nx, int column, int site[]) { int num_sol = 0; bool is_sol; int i, j; // Try to build a house in each line of column for (i=0; i<nx; i++) { site[column] = i; // Check if this placement is still a solution is_sol = true; for (j=column-1; j>=0; j--) { if ((site[column] == site[j]) || (site[column] == site[j] - (column-j)) || (site[column] == site[j] + (column-j))) { is_sol = false; break; } } if (is_sol) { if (column == nx-1) { // If this is the last column, printout the solution num_sol += 1; } else { // The placement is not complete. // Try to place the house on the next column num_sol += slave_build_house(nx, column+1, site); } } } return num_sol; } int master_build_house(int nx, int column, int site[], int *scnt, int *rcnt) { int num_sol = 0; bool is_sol; int i, j; // Try to build a house in each line of column for (i=0; i<nx; i++) { site[column] = i; // Check if this placement is still a solution is_sol = true; for (j=column-1; j>=0; j--) { if ((site[column] == site[j]) || (site[column] == site[j] - (column-j)) || (site[column] == site[j] + (column-j))) { is_sol = false; break; } } if (is_sol) { if (column == nx-1) { // If this is the last column, printout the solution num_sol += 1; } else if (column == THRES-1) { num_sol += operate_slave(nx, site, rcnt); *scnt += 1; } else { // The placement is not complete. // Try to place the house on the next column num_sol += master_build_house(nx, column+1, site, scnt, rcnt); } } } return num_sol; } void main(int argc, char **argv) { int num_sol; int nx=17; int *site; struct timeval start, end; int nprocs, myrank, ready, work, rslt; MPI_Status stat; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); if(!myrank) printf("nx=%d\n", nx); site = (int*)malloc(nx*sizeof(int)); gettimeofday(&start, NULL); if(!myrank){ int scnt = 0, rcnt = 0, i, fin = 0; num_sol = master_build_house(nx, 0, site, &scnt, &rcnt); while(rcnt < scnt){ MPI_Recv(&ready, 1, MPI_INT, MPI_ANY_SOURCE, READY_TAG, MPI_COMM_WORLD, &stat); if(ready == READY_STATE){ work = FINISH; MPI_Send(&work, 1, MPI_INT, stat.MPI_SOURCE, WORK_TAG, MPI_COMM_WORLD); fin++; } else{ MPI_Recv(&rslt, 1, MPI_INT, stat.MPI_SOURCE, RSLT_TAG, MPI_COMM_WORLD, &stat); rcnt += 1; num_sol += rslt; } } for(i=0; i<nprocs-1-fin; i++){ MPI_Recv(&ready, 1, MPI_INT, MPI_ANY_SOURCE, READY_TAG, MPI_COMM_WORLD, &stat); work = FINISH; MPI_Send(&work, 1, MPI_INT, stat.MPI_SOURCE, WORK_TAG, MPI_COMM_WORLD); } } else{ ready = READY_STATE; MPI_Send(&ready, 1, MPI_INT, 0, READY_TAG, MPI_COMM_WORLD); MPI_Recv(&work, 1, MPI_INT, 0, WORK_TAG, MPI_COMM_WORLD, &stat); while(work == WORK){ MPI_Recv(site, THRES, MPI_INT, 0, SITE_TAG, MPI_COMM_WORLD, &stat); rslt = slave_build_house(nx, THRES, site); ready = WRITING_STATE; MPI_Send(&ready, 1, MPI_INT, 0, READY_TAG, MPI_COMM_WORLD); MPI_Send(&rslt, 1, MPI_INT, 0, RSLT_TAG, MPI_COMM_WORLD); ready = READY_STATE; MPI_Send(&ready, 1, MPI_INT, 0, READY_TAG, MPI_COMM_WORLD); MPI_Recv(&work, 1, MPI_INT, 0, WORK_TAG, MPI_COMM_WORLD, &stat); } } gettimeofday(&end, NULL); if(!myrank){ printf("num_sol=%d\n", num_sol); printf("elapsed time=%.6lf sec\n", time_diff(start,end)); } MPI_Finalize(); }
'Parallel Programming' 카테고리의 다른 글
KSC 2015 2번 문제 및 답안 (0) | 2016.10.01 |
---|---|
KSC 2015 1번 문제 및 답안 (0) | 2016.10.01 |
KSC 2014 2번 문제 및 답안 (0) | 2016.10.01 |
KSC 2014 1번 문제 및 답안 (0) | 2016.10.01 |
KSC 2013 3번 문제 및 답안 (0) | 2016.10.01 |
댓글