Created
November 22, 2020 22:16
-
-
Save khokm/05d99fe46a01177f5f82e1000a604975 to your computer and use it in GitHub Desktop.
Вычисление количества простых чисел на промежутке при помощи OpenMPI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <math.h> | |
#include <mpi.h> | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
int find_prime_count(int start, int end) | |
{ | |
if (start % 2 == 0) { | |
puts("Первое проверяемое число дожно быть нечетным"); | |
exit(EXIT_FAILURE); | |
} | |
int count = 0; | |
for (uint32_t num = start; num < end; num += 2) { | |
bool isPrime = true; | |
uint32_t lim = (uint32_t)sqrt(num) + 1; | |
for (uint32_t i = 2; i < lim; i++) { | |
if (num % i == 0) { | |
isPrime = false; | |
break; | |
} | |
} | |
if (isPrime) { | |
count++; | |
} | |
} | |
return count; | |
} | |
int get_prime_limit(int rank) | |
{ | |
const int coof = 2000000; | |
int x = coof * (rank + 1); | |
return x / log(x) + 10000; | |
} | |
int get_limit(int argc, char **argv) | |
{ | |
return argc > 1 ? atoi(argv[1]) : 1000000; | |
} | |
int main(int argc, char **argv) | |
{ | |
// Initialize the MPI environment | |
MPI_Init(&argc, &argv); | |
int proc_count; | |
int my_rank; | |
// Get the number of processes | |
MPI_Comm_size(MPI_COMM_WORLD, &proc_count); | |
// Get the rank of the process | |
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); | |
//Размер ряда чисел, в котором будет вестись поиск. | |
int limit = get_limit(argc, argv); | |
//Рассчитаем размер ряда чисел для каждого процессора. | |
int range_per_proc = limit / proc_count; | |
if (my_rank == 0) { | |
printf("Запущено %d процессов.\n", proc_count); | |
printf("Ищем простые числа от 1 до %d\n", limit); | |
if (limit % proc_count != 0) { | |
puts("Кол-во процессов должно быть кратно размеру ряда."); | |
exit(EXIT_FAILURE); | |
} | |
} | |
//Подождем окончание вывода сообщений процессором #0 | |
MPI_Barrier(MPI_COMM_WORLD); | |
double starttime; | |
if (my_rank == 0) { | |
starttime = MPI_Wtime(); | |
} | |
int prime_count = 0; | |
if (my_rank == 0) { | |
//для первого ряда также включаем число 2 | |
prime_count = find_prime_count(3, range_per_proc) + 1; | |
} else { | |
int start = my_rank * range_per_proc + 1; | |
int end = start + range_per_proc; | |
prime_count = find_prime_count(start, end); | |
} | |
printf("Кол-во простых чисел (процессор %d): %d\n", my_rank, prime_count); | |
//Ждем и складываем результаты всех процессов. | |
int total_count; | |
MPI_Reduce(&prime_count, &total_count, 1, MPI_INT, MPI_SUM, 0, | |
MPI_COMM_WORLD); | |
//Ждем окончания работы всех процессов; | |
// MPI_Barrier(MPI_COMM_WORLD); | |
if (my_rank == 0) { | |
double total_time = MPI_Wtime() - starttime; | |
printf("СУММАРНОЕ КОЛ-ВО ПРОСТЫХ ЧИСЕЛ: %d\n", total_count); | |
printf("Всего затрачено времени: %f (секунд)\n", total_time); | |
} | |
MPI_Finalize(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment