/* * Author : DaeGon Kim * Date : 2008/09/06 * Desc : Sequential Sieve of Eratosthenes algorithm */ #include코드에는 전혀 한글이 없습니다. 제가 쓰는 대부분의 컴퓨터는 한글 입력이 지원되지 않습니다. 그래서 한글로 된 프로그램은 컴파일이 되지 않아 프로그램에는 한글을 사용하지 않는 버릇이 있기 때문입니다. 양해해주시기 바랍니다. 그리고 제가 영어로 주석을 달았다고 생각이 들진 않거든요.#include int main(int argc, char **argv) { // Commandline arg checking if ( argc < 2 ) { printf("Usage : %s [N]n", argv[0]); return 0; } int N = atoi(argv[1]); int i; // Check N. if ( N <= 4 ) { printf("N must be greater than 4.n"); return 0; } // memory allocation for arrays int *arrays = (int *)malloc(sizeof(int)*(N+1)); if ( arrays == NULL ) { printf("Fail to allocate memory for arrays.n"); return 0; } // initialization for ( i=0 ; i <= N ; i++ ) { arrays[i] = 1; } // main algorithm int current_prime = 2; while ( current_prime * current_prime <= N ) { for ( i = 2*current_prime ; i <= N ; i += current_prime ) { arrays[i] = 0; } for ( i=current_prime+1; arrays[i] == 0 ; i++ ); current_prime = i; } // print primes and total printf("Primes up to %dn", N); int total = 0; for ( i = 2 ; i <= N ; i++ ) { if ( arrays[i] == 1 ) { printf("%d ", i); total++; } } printf("nThe total number of primes is %d.n", total); free(arrays); return 0; }
/* * Author : DaeGon Kim * Date : 2008/09/06 * Desc : MPI sieve of Eratosthenes algorithm */ #include첫번째 일반 C 프로그램에서 적지 않는 변화가 있었던 같지만 대부분의 변화는 각 프로세서가 전체 배열의 일부를 가짐으로 생기는 변화입니다. 같이 비교해 가면서 읽어보시기 바랍니다. 필자가 가진 MPI 프로그램이 있었지만 비교를 위해 첫번째 프로그램에서 시작해서 새로이 작성된 프로그램입니다.#include #include #include // for ceil function #define MIN(a,b) ((a)>(b) ? (b) : (a) ) #define MAX(a,b) ((a)>(b) ? (a) : (b) ) int main(int argc, char **argv) { int rank, size; int BLOCK_SIZE; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); // Commandline arg checking if ( argc < 2 ) { if ( rank == 0 ) printf("Usage : %s [N]n", argv[0]); MPI_Finalize(); return 0; } int N = atoi(argv[1]); int i; // Check N. if ( N <= 4 ) { if ( rank == 0 ) printf("N must be greater than 4.n"); MPI_Finalize(); return 0; } BLOCK_SIZE = ceil((double)(N+1)/(double)size); // Checking whether the first processor has all the primes up to sqrt(n). if ( BLOCK_SIZE < sqrt(N) ) { if ( rank == 0 ) printf("All the primes up to sqrt(N) must be in the first processor.n"); MPI_Finalize(); return 0; } int *arrays = (int *)malloc(sizeof(int)*(BLOCK_SIZE)); if ( arrays == NULL ) { printf("Fail to allocate memory for arrays.n"); MPI_Abort(MPI_COMM_WORLD, -1); return 0; } int low_value = rank * BLOCK_SIZE; int high_value = MIN((rank+1)*BLOCK_SIZE-1,N); for ( i=0 ; i < BLOCK_SIZE ; i++ ) { arrays[i] = 1; } int current_prime = 2; int first = 0; while ( current_prime * current_prime <= N ) { first = 2 * current_prime; if ( first < low_value ) { if ( low_value % current_prime == 0 ) { first = low_value; } else { first = low_value + (current_prime - (low_value%current_prime)); } } for ( i = first ; i <= high_value ; i += current_prime ) { arrays[i-low_value] = 0; } if ( rank == 0 ) { for ( i=current_prime+1; arrays[i] == 0 ; i++ ); current_prime = i; } MPI_Bcast(¤t_prime, 1, MPI_INT, 0, MPI_COMM_WORLD); } //printf("Primes up to %dn", N); int total = 0; for ( i = MAX(2,low_value) ; i <= high_value ; i++ ) { if ( arrays[i-low_value] == 1 ) { //printf("%d ", i); total++; } } int total_count; MPI_Reduce(&total, &total_count, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if ( rank == 0 ) printf("The total number of primes is %d.n", total_count); free(arrays); MPI_Finalize(); return 0; }
MPI_Bcast(¤t_prime, 1, MPI_INT, 0, MPI_COMM_WORLD);두번째로 가정했던 N의 제곱근까지의 모든 소수를 첫번째 프로세서가 가지고 있다는 가정은 이 문장 때문입니다. 그 가정 없이는 어떤 프로세서가 보낼 지 알 수 없기 때문이지요.
MPI_Reduce(&total, &total_count, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);지금까지 우리는 MPI가 가진 Collective 함수라고 부르는 것 중에 두 개를 살펴보았습니다. 다음 기사에서는 실제 소수들을 하나의 프로세서에 모아서 출력해 보도록 하겠습니다.
최신 콘텐츠