Skip to content

Z1mina/parall_programming

Repository files navigation

Отчет по лабораторной работе №2

Зиминой Евгении (гр. 6214-100503D)


Цель работы

Исследовать эффективность параллельного выполнения программы умножения квадратных матриц с использованием технологии OpenMP. Определить зависимость времени выполнения от размера матриц и количества потоков.


Исходные данные

Файлы:

  • A_matrix.txt — матрица A
  • B_matrix.txt — матрица B

Матрицы генерируются случайным образом в программе.


Выходные данные

  • Result.txt — результат перемножения матриц
  • время выполнения программы
  • объем задачи
  • проверка корректности (Python, NumPy)

Исходный код решения

#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>

#include <omp.h>

void multiply(int n, int A[2000][2000], int B[2000][2000], int C[2000][2000])
{
    int i, j, k;
    #pragma omp parallel for
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++) {
            C[i][j] = 0;
            for (k = 0; k < n; k++)
                C[i][j] += A[i][k] * B[k][j];
        }
}

int main()
{
    int n;
    int threads;

    std::cout << "Enter matrix size: ";
    std::cin >> n;

    std::cout << "Enter number of threads: ";
    std::cin >> threads;

    omp_set_num_threads(threads);

    std::cout << "Max available threads: " << omp_get_max_threads() << "\n";

    static int A[2000][2000];
    static int B[2000][2000];
    static int C[2000][2000];

    std::ofstream Afile("A_matrix.txt");
    std::ofstream Bfile("B_matrix.txt");

    srand(time(0));

    Afile << n << "\n";
    Bfile << n << "\n";

    int i, j;

    // генерация и запись
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            A[i][j] = rand() % 10;
            B[i][j] = rand() % 10;

            Afile << A[i][j] << " ";
            Bfile << B[i][j] << " ";
        }
        Afile << "\n";
        Bfile << "\n";
    }

    Afile.close();
    Bfile.close();

    double start = omp_get_wtime();

    multiply(n, A, B, C);

    double end = omp_get_wtime();

    std::ofstream Cfile("Result.txt");

    Cfile << n << "\n";
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++)
            Cfile << C[i][j] << " ";
        Cfile << "\n";
    }

    Cfile.close();

    double t = end - start;

    std::cout << "\n    RESULT    \n";
    std::cout << "Matrix size: " << n << " x " << n << "\n";
    std::cout << "Threads: " << threads << "\n";
    std::cout << "Time: " << t << " sec\n";
    std::cout << "Operations: " << (long long)n * n * n << "\n";

    return 0;
}

Проверка корректности

import numpy as np

A = np.loadtxt("A_matrix.txt", skiprows=1)
B = np.loadtxt("B_matrix.txt", skiprows=1)
C = np.loadtxt("Result.txt", skiprows=1)

R = A @ B

if (R == C).all():
    print("Matrix multiplication is correct.")
else:
    print("Matrix multiplication is wrong.")

Результаты экспериментов

N (размер) Потоки Время (сек) Объём задачи (N³)
200 1 0,054898 8000000
200 2 0,0617131 8000000
200 4 0,0585114 8000000
400 1 0,364215 64000000
400 2 0,472091 64000000
400 4 0,453813 64000000
800 1 3,99106 512000000
800 2 3,29522 512000000
800 4 2,97407 512000000
1200 1 12,8639 1728000000
1200 2 11,8587 1728000000
1200 4 8,81476 1728000000
1400 1 21,1614 2744000000
1400 2 23,8853 2744000000
1400 4 22,8413 2744000000
1600 1 30,529 4096000000
1600 2 28,3173 4096000000
1600 4 23,9287 4096000000

Анализ результатов

В ходе экспериментов была проверена зависимость времени выполнения программы от размера матрицы и количества потоков.

При небольших размерах матриц (N = 200 и 400) увеличение количества потоков не даёт ускорения. Более того, время выполнения даже немного увеличивается. Это связано с тем, что на маленьких задачах затраты на создание потоков больше, чем польза от распараллеливания.

При размере матрицы N = 800 уже начинает наблюдаться ускорение. При использовании 4 потоков программа работает быстрее, чем при одном.

При больших размерах матриц (N = 1200, 1400, 1600) ускорение становится заметным. Чем больше потоков, тем меньше время выполнения программы.

Таким образом, распараллеливание эффективно только для задач с большим объёмом данных.

График зависимости времени от количества потоков

График

Вывод

В данной работе была реализована параллельная версия умножения матриц с использованием OpenMP.

В результате экспериментов было установлено, что при небольших размерах матриц распараллеливание не даёт выигрыша по времени. Однако при увеличении размера задачи использование нескольких потоков позволяет ускорить выполнение программы.

Это показывает, что параллельные вычисления имеет смысл применять для больших задач.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors