Тексерген: Қасымбек Н. М. Орындаған: Жеңіс Аяуылым кн1902 Алматы – 2022 Кесте: T(уақыт)



Дата05.03.2023
өлшемі332,29 Kb.
#71650

Қазақстан Республикасы Білім және Ғылым министрлігі
Әл-Фараби атындағы Қазақ Ұлттық Университеті


Факультет: Ақпараттық технологиялар
Мамандық: Компьютерлік ғылымдар



СӨЖ

ТАҚЫРЫБЫ: MPI және OpenMP уақыт айырмашылығы

Тексерген: Қасымбек Н. М.
Орындаған: Жеңіс Аяуылым КН1902

Алматы – 2022
Кесте:
T(уақыт)



n \ P

1

2

4

8

MPI

OpenMP

MPI

OpenMP

MPI

OpenMP

MPI

OpenMP

10

0.00008

0.0191

0.0026

0.0164

0.003

0.0157

0.0038

0.0184

50

0.00006

0.00036

0.0015

0.0023

0.0022

0.0228

-

0.0522

100

0.00011

-

-

0.039

-

0.02

-

0.0188



MPI, n=10, P=1;





MPI, n=10, P=2;



MPI, n=10, P=4;



MPI, n=10, P=8;



Код:
#include "mpi.h"
#include
#include
#include
#include
#include
using namespace std;
int main(int argc, char* argv[])
{
int rank, size;
int a_cols, a_size, b_size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Status status;
srand(time(0) + rank);

a_cols = 10;


a_size = a_cols * a_cols;

double* a_matrix = new double[a_size];


double* b_matrix = new double[a_cols];
double* x_old = new double[a_cols];
double* x_new = new double[a_cols];
int* count = new int[size];
int* displacement = new int[size];

double e = 0.001;


if (rank == 0) {
for (int i = 0; i < a_cols; i++) {
double sum = 0.0;
for (int j = 0; j < a_cols; j++) {
if (i == j) continue;
a_matrix[i * a_cols + j] = (10 - 1) * ((double)rand() / (double)RAND_MAX) + 1;
sum += a_matrix[i * a_cols + j];
}
a_matrix[i * a_cols + i] = sum + 10.0;
b_matrix[i] = sum * 2 - 22.4;
x_old[i] = 0.0;
x_new[i] = 0.0;
}

printf("Matrix A\n");


for (int i = 0; i < a_cols; i++) {
for (int j = 0; j < a_cols; j++) {
printf("%.1f\t", a_matrix[i * a_cols + j]);
}
printf("\n");
}

printf("\nMatrix B \n");


for (int i = 0; i < a_cols; i++) {
printf("%.1f\t", b_matrix[i]);
}
printf("\n");

int full = a_cols / size;


int remaind = a_cols % size;
int i = 0;
for (int i = 0; i < size; i++) {
count[i] = full;
}
while (remaind != 0) {
count[i]++;
remaind--;
if (i < size - 1) i++;
else i = 0;
}

displacement[0] = 0;


for (int i = 1; i < a_cols; i++) {
displacement[i] = displacement[i - 1] + count[i - 1];
}
printf("\nIn each process: ");
for (int i = 0; i < size; i++) {
printf("%d ", count[i]);
}
printf("\n");

printf("\nDisplacement: ");


for (int i = 0; i < size; i++) {
printf("%d ", displacement[i]);
}
printf("\n");

}


double time = MPI_Wtime();

MPI_Bcast(a_matrix, a_size, MPI_DOUBLE, 0, MPI_COMM_WORLD);


MPI_Bcast(b_matrix, a_cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(x_new, a_cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(x_old, a_cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(count, a_cols, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(displacement, a_cols, MPI_INT, 0, MPI_COMM_WORLD);

int x_count = count[rank];


double max = 0.0;

do {
for (int k = 0; k < x_count; k++) {


int current_row = rank * x_count + k;
for (int i = 0; i < a_cols; i++) {
if (i == k) continue;
x_new[current_row] += x_old[i] * a_matrix[current_row * a_cols + i];
}
x_new[current_row] = (b_matrix[current_row] - x_new[current_row]) / (double)a_matrix[current_row * a_cols + current_row];
}
int sub_max = abs(x_new[rank * x_count + 0] - x_old[rank * x_count + 0]);
for (int i = 1; i < x_count; i++)
if (abs(x_new[rank * x_count + i] - x_old[rank * x_count + i]) > max)
max = abs(x_new[rank * x_count + i] - x_old[rank * x_count + i]);
MPI_Allreduce(&sub_max, &max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);

MPI_Allgatherv(&x_new[displacement[rank]], count[rank], MPI_DOUBLE, x_old, count, displacement, MPI_DOUBLE, MPI_COMM_WORLD);


} while (max >= e);

printf("[%d] x: ", rank);


for (int k = 0; k < x_count; k++) {
printf("%.5f ", x_new[rank * x_count + k]);
}
printf("\n");

time = MPI_Wtime() - time;


if (rank == 0) {


printf("\n TIME: %f\n", time);
}

MPI_Finalize();


return 0;


}
OpenMP, n=10, P=1;



OpenMP, n=10, P=2;



OpenMP, n=10, P=4;



OpenMP, n=10, P=8;





Код:
#include
#include
#include
#include
#include
#include

int main(int argc, char** argv);


int main(int argc, char** argv) {


srand(time(0));
int n = 10;
int i, h, g, j;
double** a_matrix = new double* [n];
for (int i = 0; i < n; ++i)
a_matrix[i] = new double[n];
double* b_matrix = new double[n];
double* x_old = new double[n];
double* x_new = new double[n];

double eps = 0.001;


double diff;

for (i = 0; i < n; i++) {


for (j = 0; j < n; j++) {
if (i == j) {
a_matrix[i][j] = 1000 + rand() % 2000;
}
else {
a_matrix[i][j] = 10 + rand() % 20;
}
}
}
for (i = 0; i < n; i++) {
b_matrix[i] = 10 + rand() % 50;
}

for (i = 0; i < n; i++)


{
x_old[i] = 0.0;
}

for (i = 0; i < n; i++)


{
x_new[i] = 0.0;
}

printf("Matrix A\n");


for (i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%.1f\t", a_matrix[i][j]);
}
printf("\n");
}

printf("\nMatrix B \n");


for (i = 0; i < n; i++) {
printf("%.1f\t", b_matrix[i]);
}
printf("\n");

double start, end;


int threadsNum = 8;
omp_set_num_threads(threadsNum);
start = omp_get_wtime();

#pragma omp parallel shared(a_matrix, b_matrix, x_old, x_new, diff, eps) private(i, h, g) num_threads(threadsNum)


do {
#pragma omp parallel for
for (int i = 0; i < n; i++) {
x_old[i] = b_matrix[i];
#pragma omp parallel for
for (int g = 0; g < n; g++) {
if (i != g)
x_old[i] -= a_matrix[i][g] * x_new[g];
}
x_old[i] /= a_matrix[i][i];
}
diff = fabs(x_new[0] - x_old[0]);
#pragma omp parallel for
for (int h = 0; h < n; h++) {
if (fabs(x_new[h] - x_old[h]) > diff)
diff = fabs(x_new[h] - x_old[h]);
x_new[h] = x_old[h];
}
} while (diff > eps);
#pragma omp parallel for
for (i = 0; i < n; i++) {
printf("\nThread %d works on element %d \n", omp_get_thread_num(), i);
std::cout << x_new[i] << " ";
}

end = omp_get_wtime();


printf_s("Time: %f \n", end - start);
}
Қорытынды
Мен 10 элемент үшін уақыт есептегенде экранға барлық данныйларды шығардым, алайда кейін 50 және 100 элементтер үшін тек ғана уақытты экранға шығардым. Сол себептен менің зерттеуім нақты дұрыс шықпады. Бірақ оған қарамастан кестедегі ақпаратқа сүйене отырып бұл есепте MPI тезірек жұмыс жасайтынын көрдім. Бұл дәл дұрыс болжау емес, себебі 100 элемент үшін есептеулерді менің ноутбугым көтермей қалды.


Достарыңызбен бөлісу:




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет