Computer Science
Practise 找質數 - 單機版程式 vs. 平行版程式
題目
利用 The Sieve of Eratosthenes 演算法找出質數
單機版程式
#include <bits/stdc++.h>
#define ALLNUM 100000000
using namespace std;
long long arr[ALLNUM + 1] = {0};
int main() {
int k = 2;
long start = clock();
for (int i = 2; i <= ALLNUM;) {
k = i;
if (k * k > ALLNUM) {
break;
}
int mark = k + k;
while (mark <= ALLNUM) {
arr[mark] = 1;
mark += k;
}
i++;
while (arr[i] != 0) {
i++;
}
}
long end = clock();
int ans = 0;
for (int i = 2; i <= ALLNUM; i++) {
if (arr[i] == 0) {
ans++;
}
}
printf("%d\n", ans);
cout << "\033[36mTotal: " << (end - start) / 1000.0 << " (sec)\033[0m"
<< endl;
return 0;
}
平行版程式
#include <bits/stdc++.h>
#include <mpi.h>
#define ALLNUM 100000000
using namespace std;
long long arr[ALLNUM + 1] = {0};
long long ans = 0;
int main() {
MPI_Init(NULL, NULL);
int world_size, world_rank;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int size = ALLNUM / world_size;
int from = world_rank * size;
int to =
(world_rank != world_size - 1 ? (world_rank + 1) * size - 1 : ALLNUM);
int k = 2;
arr[0] = 1;
arr[1] = 1;
double start = MPI_Wtime();
for (int i = from; i <= to;) {
MPI_Bcast(&k, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (k * k > ALLNUM) {
break;
}
if (k < to) {
int mark = from;
while (mark % k != 0 || mark == 0) {
mark += 1;
}
if (mark == k) {
mark += k;
}
while (mark <= to) {
arr[mark] = 1;
mark += k;
} // marking
i++;
while (arr[i] != 0) {
i++;
} // find K
}
int newK = i;
MPI_Reduce(&newK, &k, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
}
int count = 0;
for (int i = from; i <= to; i++) {
if (arr[i] == 0 && i != 0 && i != 1) {
count++;
}
}
MPI_Reduce(&count, &ans, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
double end = MPI_Wtime();
MPI_Finalize();
if (world_rank == 0) {
cout << ans << endl;
cout << "\033[36mTotal: " << (end - start) << " (sec)\033[0m" << endl;
}
return 0;
}