Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include "mpi.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <time.h>
- #include <conio.h>
- #include <string.h>
- int main(int argc, char* argv[])
- {
- int size;
- int *chisla;
- int *chisla_buf = NULL;
- int myrank, num_proc;
- int TAG = 0;
- char processor_name[MPI_MAX_PROCESSOR_NAME];
- int namelen = MPI_MAX_PROCESSOR_NAME;
- double startwtime, endwtime;
- FILE *prchisla;
- int fl;
- char ch[50];
- int porog, diapason, ost, start, end;
- int i, j, flag;
- int buf, kol;
- MPI_Init(&argc, &argv); // инициализируем работу программы MPI
- // Инициализируем счетчик отсчета времени работы программы
- // Определяем номер процессора
- MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
- // Определяем число процессоров
- MPI_Comm_size(MPI_COMM_WORLD, &size);
- // Определяем имя компьютера на котором запущен процесс
- MPI_Get_processor_name(processor_name, &namelen);
- // Выводим полученную информацию на экран
- fprintf(stderr, "\nProcess %d started working at machine %s\n", myrank, processor_name);
- fflush(stdout);
- if (myrank == 0) // усли это главный процессб то
- {
- // открываем на запись файл, в который будем записывать найденные простые числа
- prchisla = fopen("primes.txt", "w");
- // Вводим число в пределах кторого необходимо будет найти все простые числа
- printf("\nEnter prime numbers seeking range:");
- fflush(stdout);
- scanf("%s", &ch); // Считываем вводимое число посимвольно
- porog = atoi(ch); // преобразуем ввседенное число
- startwtime = MPI_Wtime(); // Инициализируем счетчик отсчета времени
- diapason = porog / size; // Количество чисел для анализа каждым поцессом
- ost = porog - diapason * size; // Остаток от деления
- // Главный процесс посылает остальным процессам диапазон анализа
- MPI_Bcast(&diapason, 1, MPI_INT, 0, MPI_COMM_WORLD);
- MPI_Barrier(MPI_COMM_WORLD);
- // Ожидаем пока все процессы получат данные
- start = (size - 1) * diapason + 2; // Определяем начальное число анализа
- end = (size * diapason) + ost; // Определяем конечное число анализа
- chisla = (int*)malloc((diapason + ost) * sizeof(int));
- // Инициализируем массивы для хранения результатов анализа
- chisla_buf = (int*)malloc(diapason * sizeof(int));
- for (i = 0; i < diapason; i++)
- chisla[i] = 0; // Обнуляем инициализированные массивы
- for (i = 0; i < diapason; i++)
- chisla_buf[i] = 0;
- kol = 0;
- if (start == 2) // Если начальное число анализа равно 2,
- {
- chisla[kol] = 2; // то заносим его в массив результата
- kol++;
- start = start + 1;
- } //и переходим к дальнейшему анализу
- for (i = start; i <= end; i++) // Поочередно берем каждый из элементов
- {
- j = 1;
- flag = 1; // Устанавливаем флаг в 1
- do
- {
- j++;
- // Начинаем делить на 2 все возможные делители
- // Первый раз j = 2.
- buf = i / j;
- if ((buf * j) == i) // Если число поделилось нацело, то оно не является простым
- flag = 0;
- } // Анализ продолжается пока не будут проверены все делители и флаг не будет равен 1
- while ((j < (i - 1)) && (flag == 1));
- if (flag == 1) // Если флаг остался равен 1
- {
- chisla[kol] = j + 1; // то это простое число и мы заносим его в массив
- kol++;
- }
- }
- if (size > 1) // Если в вычислениях учавствует более 1 процесса
- {
- for (j = 1; j < size; j++)
- { // то принимаем данные от каждого из них
- num_proc = j;
- MPI_Recv(chisla_buf, diapason, MPI_INT, num_proc, TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
- i = 0;
- while ((i < diapason) && (chisla_buf[i] != 0))
- {
- if (chisla_buf[i] != 0) //Заносим принятые данные в выходной файл
- {
- fprintf(prchisla, "%d \n", chisla_buf[i]);
- fflush(prchisla);
- }
- i++;
- }
- }
- }
- i = 0; // После этого заносим в выходной файл данные, полученные главным процессом
- while ((i < (diapason + ost)) && (chisla[i] != 0))
- {
- if (chisla[i] != 0)
- {
- fprintf(prchisla, "%d \n", chisla[i]);
- fflush(prchisla);
- }
- i++;
- }
- MPI_Barrier(MPI_COMM_WORLD); // ожидаем пока все процессы вызовут эту функцию
- endwtime = MPI_Wtime();
- printf("\n wall clock time = %f\n", endwtime - startwtime); // Выводим на экран время работы программы.
- fflush(stdout);
- printf("\nAnalysis complete!\n");
- fflush(stdout);
- free(chisla); // освобождаем динамическую память
- free(chisla_buf);
- fclose(prchisla);
- }
- else // Если это не главный процесс, то принимаем данные от главного процесса
- {
- MPI_Bcast(&diapason, 1, MPI_INT, 0, MPI_COMM_WORLD);
- printf("\n Process %d received data from manager process, diapason = %d\n", myrank, diapason);
- fflush(stdout);
- MPI_Barrier(MPI_COMM_WORLD); // Ожидаем пока все процессы вызовут эту функцию
- start = (myrank - 1) * diapason + 2; // Определяем начальное число анализа
- end = (myrank * diapason) + 1; // Определяем конечное число анализа
- chisla = (int*)malloc(diapason * sizeof(int)); // Инициализируем массив для хранения резудьтатов анализа
- for (i = 0; i < diapason; i++)
- chisla[i] = 0; // Обнуляем инициализированные массивы
- kol = 0;
- if (start == 2) // Если начальное число анализа равно 2,
- {
- chisla[kol] = 2; // то заносим его в массив результата
- kol++; // и переходим к дальнейшему анализу
- start++;
- }
- for (i = start; i <= end; i++) // поочередно берем каждый из элементов
- {
- j = 1;
- flag = 1; // Устанавливаем флаг в 1
- do
- {
- j++; // Начинаем делить на всевозможные делители. Первый раз j = 2.
- buf = i / j;
- if ((buf * j) == i) // Если чисо поделилось нацело, то оно НЕ является простым
- flag = 0; // и поэтому флаг устанавливается в 0
- }
- while ((j < (i - 1)) && (flag == 1)); // Анализ продолжается пока не будут проверены все делители и флаг не будет равен 1
- if (flag == 1) // Если флаг остался равен 1, то это простое число и мы заносим его в массив
- {
- chisla[kol] = j + 1;
- kol++;
- }
- }
- MPI_Send(chisla, diapason, MPI_INT, 0, TAG, MPI_COMM_WORLD); // Передаем массив с результатами главному процессору
- MPI_Barrier(MPI_COMM_WORLD); // Ожмдаем пока все процессы вызовут эту функцию
- free(chisla_buf); // освобождаем динамическую память
- }
- MPI_Finalize(); // Завершаем работу программы MPI
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement