Мне удалось реализовать одношаговую генерацию с использованием Open MPI, распределив вычисления Мандельброта по 4 процессорам. Теперь я хочу добавить функцию масштабирования, но не знаю, с чего начать.
void scatter_gather_mandelbrot(int size_of_cluster, double scale, double cx, double cy){
// Determine root's rank
int root_rank = 0;
// Get my rank
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int max_iter = 512;
double recvbuf_r1[SIZE/2]={0};
double recvbuf_r2[SIZE/2]={0};
//Scattering
if (my_rank == root_rank) {
double r1[SIZE]; // ilk yarısını 0 ve 1'ye, ikinci yarısını 2 ve 3'e
double r2[SIZE]; // ilk yarısını 0 ve 2'e, ikinci yarısını 1 ve 3'e
// Define the range and resolution of the fractal
double xmin = -scale, xmax = scale, ymin = -scale, ymax = scale;
for (int i = 0; i < SIZE; ++i) {
r1[i] = xmin + (i * (xmax - xmin) / (SIZE - 1));
r2[i] = ymin + (i * (ymax - ymin) / (SIZE - 1));
}
printf("\n");
int counts[4];
int displacements_r1[4] = {0, 0, SIZE/2, SIZE/2};
int displacements_r2[4] = {0, SIZE/2, 0, SIZE/2};
for (int i = 0; i < size_of_cluster; i++)
{
counts[i] = SIZE/2;
}
MPI_Scatterv(r1, counts, displacements_r1, MPI_DOUBLE, recvbuf_r1, SIZE/2, MPI_DOUBLE, root_rank, MPI_COMM_WORLD);
MPI_Scatterv(r1, counts, displacements_r2, MPI_DOUBLE, recvbuf_r2, SIZE/2, MPI_DOUBLE, root_rank, MPI_COMM_WORLD);
}
else {
MPI_Scatterv(NULL, NULL, NULL, MPI_DOUBLE, recvbuf_r1, SIZE/2, MPI_DOUBLE, root_rank, MPI_COMM_WORLD);
MPI_Scatterv(NULL, NULL, NULL, MPI_DOUBLE, recvbuf_r2, SIZE/2, MPI_DOUBLE, root_rank, MPI_COMM_WORLD);
}
MPI_Barrier(MPI_COMM_WORLD);
int local_result[SIZE/2][SIZE/2];
for (int i = 0; i < SIZE/2; ++i) {
for (int j = 0; j < SIZE/2; ++j) {
complex c(cx+recvbuf_r1[j], cy+recvbuf_r2[i]);
local_result[i][j] = mandelbrot(c, max_iter);
}
}
MPI_Barrier(MPI_COMM_WORLD);
// NxN matrix 4 equal blocks
const int NPROWS=2; // block row width
const int NPCOLS=2; // block column length
const int CELLS_PER_ROW = SIZE/NPROWS; // number of rows in block
const int CELLS_PER_COLUMN = SIZE/NPCOLS; // number of cols in block
const int BLOCK_SIZE = CELLS_PER_ROW * CELLS_PER_COLUMN;
// Create the vector datatype
MPI_Datatype column_not_resized;
MPI_Type_vector(CELLS_PER_COLUMN, CELLS_PER_ROW, SIZE, MPI_INT, &column_not_resized);
// Resize it to make sure it is interleaved when repeated
MPI_Datatype column_resized;
MPI_Type_create_resized(column_not_resized, 0, sizeof(int), &column_resized);
MPI_Type_commit(&column_resized);
// Gathering
if (my_rank == root_rank) {
int mandelbrotdata[SIZE][SIZE];
int counts[4];
int displacements[4] = {0, SIZE*(SIZE/2), (SIZE/2), SIZE*(SIZE/2)+(SIZE/2)};
for (int i = 0; i < 4; i++) counts[i] = BLOCK_SIZE;
printf("\n");
MPI_Gatherv(local_result, BLOCK_SIZE, MPI_INT, mandelbrotdata, counts, displacements, column_resized, root_rank, MPI_COMM_WORLD);
draw(mandelbrotdata, max_iter);
}
else {
MPI_Gatherv(local_result, BLOCK_SIZE, MPI_INT, NULL, NULL, NULL, column_resized, root_rank, MPI_COMM_WORLD);
}
}
int main(int argc, char* argv[])
{
MPI_Init(&argc, &argv);
// Get number of processes and check that 4 processes are used
int size_of_cluster;
MPI_Comm_size(MPI_COMM_WORLD, &size_of_cluster);
if(size_of_cluster != 4)
{
printf("This application is meant to be run with 4 processes.\n");
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
}
double scale = 0.3;
double cx = -1.0;
double cy = 0.0;
scatter_gather_mandelbrot(size_of_cluster, scale, cx, cy);
MPI_Finalize();
return EXIT_SUCCESS;
}
Я подумал об изменении двойного масштаба cx, cy с помощью пользовательского ввода. Но не знаю, как это реализовать. Я использую графику SFML для отображения в виде окна.
Мне удалось реализовать одношаговую генерацию с использованием Open MPI, распределив вычисления Мандельброта по 4 процессорам. Теперь я хочу добавить функцию масштабирования, но не знаю, с чего начать. [code]void scatter_gather_mandelbrot(int size_of_cluster, double scale, double cx, double cy){ // Determine root's rank int root_rank = 0;
// Get my rank int my_rank; MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
//Scattering if (my_rank == root_rank) { double r1[SIZE]; // ilk yarısını 0 ve 1'ye, ikinci yarısını 2 ve 3'e double r2[SIZE]; // ilk yarısını 0 ve 2'e, ikinci yarısını 1 ve 3'e // Define the range and resolution of the fractal double xmin = -scale, xmax = scale, ymin = -scale, ymax = scale;
for (int i = 0; i < SIZE; ++i) { r1[i] = xmin + (i * (xmax - xmin) / (SIZE - 1)); r2[i] = ymin + (i * (ymax - ymin) / (SIZE - 1)); }
for (int i = 0; i < SIZE/2; ++i) { for (int j = 0; j < SIZE/2; ++j) { complex c(cx+recvbuf_r1[j], cy+recvbuf_r2[i]); local_result[i][j] = mandelbrot(c, max_iter); } }
MPI_Barrier(MPI_COMM_WORLD);
// NxN matrix 4 equal blocks const int NPROWS=2; // block row width const int NPCOLS=2; // block column length const int CELLS_PER_ROW = SIZE/NPROWS; // number of rows in block const int CELLS_PER_COLUMN = SIZE/NPCOLS; // number of cols in block const int BLOCK_SIZE = CELLS_PER_ROW * CELLS_PER_COLUMN;
// Resize it to make sure it is interleaved when repeated MPI_Datatype column_resized; MPI_Type_create_resized(column_not_resized, 0, sizeof(int), &column_resized); MPI_Type_commit(&column_resized);
// Gathering if (my_rank == root_rank) { int mandelbrotdata[SIZE][SIZE]; int counts[4]; int displacements[4] = {0, SIZE*(SIZE/2), (SIZE/2), SIZE*(SIZE/2)+(SIZE/2)}; for (int i = 0; i < 4; i++) counts[i] = BLOCK_SIZE;
int main(int argc, char* argv[]) { MPI_Init(&argc, &argv);
// Get number of processes and check that 4 processes are used int size_of_cluster; MPI_Comm_size(MPI_COMM_WORLD, &size_of_cluster); if(size_of_cluster != 4) { printf("This application is meant to be run with 4 processes.\n"); MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); } double scale = 0.3; double cx = -1.0; double cy = 0.0; scatter_gather_mandelbrot(size_of_cluster, scale, cx, cy);
MPI_Finalize();
return EXIT_SUCCESS; } [/code] Я подумал об изменении двойного масштаба cx, cy с помощью пользовательского ввода. Но не знаю, как это реализовать. Я использую графику SFML для отображения в виде окна.
Я работаю над параллельной программой, использующей mpi4py в Python, и столкнулся с проблемой, когда данные отправляются с помощью MPI.COMM_WORLD.isend, но когда принимающий процесс пытается получить данные с помощью MPI.COMM_WORLD.irecv, он...
Я экспериментировал с вычислением множества Мандельброта на C++ на своем процессоре i9, который имеет 10 ядер и 20 потоков. Несмотря на ожидание быстрых вычислений, учитывая возможности моего процессора, реальная производительность оказалась на...
В предисловии: в настоящее время я учусь на первом курсе, и мне разрешили записаться на некоторые курсы второго курса. Из-за этого в настоящее время я разбираюсь с языком (C++), на изучение которого у меня нет времени (первокурсники в основном...
Поэтому я ранее задавал аналогичный вопрос, но не разместил достаточно кода, чтобы получить необходимую помощь. Даже если бы я вернулся и добавил этот код сейчас, я не думаю, что это будет замечено, потому что вопрос старый и на него «отвечен»....
Я написал функцию, которая использует черепаху для рисования множества Мандельброта, однако она очень медленная (около 10 минут) для любого приличного разрешения. Как я могу сделать свой код более эффективным?
import math, turtle