Параллельное умножение матриц - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Всем привет, помогите написать программу) нужно написать программу Параллельное умножение матриц, размерность матриц А 1200*768 и В 768*666 , программа заполняет матрицы А и B случайными цифрами, вычисляет матрицу С и выводит время которое было затрачено на выполнение вычисления. Размерность матриц Нашел
#include "stdafx.h"
#include "time.h"
#include "omp.h"
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#include "windows.h"
 
// Function that converts numbers form LongInt type to double type
double LiToDouble(LARGE_INTEGER x)
{
    double result = ((double)x.HighPart) * 4.294967296E9 + (double)((x).LowPart);
    return result;
}
// Function that gets the timestamp in seconds
double GetTime()
{
    LARGE_INTEGER lpFrequency, lpPerfomanceCount;
    QueryPerformanceFrequency(&lpFrequency);
    QueryPerformanceCounter(&lpPerfomanceCount);
    return LiToDouble(lpPerfomanceCount) / LiToDouble(lpFrequency);
}
// Function for simple initialization of matrix elements
void DummyDataInitialization(double* pAMatrix, double* pBMatrix, int Size)
{
    int i, j; // Loop variables
    for (i = 0; i < Size; i++)
        for (j = 0; j < Size; j++)
        {
            pAMatrix[i * Size + j] = 1;
            pBMatrix[i * Size + j] = 1;
        }
}
// Function for random initialization of matrix elements
void RandomDataInitialization(double* pAMatrix, double* pBMatrix, int Size)
{
    int i, j; // Loop variables
    srand(unsigned(clock()));
    for (i = 0; i < Size; i++)
        for (j = 0; j < Size; j++)
        {
            pAMatrix[i * Size + j] = rand() / double(1000);
            pBMatrix[i * Size + j] = rand() / double(1000);
        }
}
// Function for memory allocation and initialization of matrix elements
void ProcessInitialization(double*& pAMatrix, double*& pBMatrix, double*& pCMatrix, int& Size)
{
    // Setting the size of matricies
    do
    {
        printf("\nEnter size of matricies: ");
        scanf("%d", &Size);
        printf("\nChosen matricies' size = %d\n", Size);
        if (Size <= 0)
            printf("\nSize of objects must be greater than 0!\n");
    } while (Size <= 0);
    // Memory allocation
    pAMatrix = new double[Size * Size];
    pBMatrix = new double[Size * Size];
    pCMatrix = new double[Size * Size];
    // Initialization of matrix elements
    DummyDataInitialization(pAMatrix, pBMatrix, Size);
    for (int i = 0; i < Size * Size; i++)
    {
        pCMatrix[i] = 0;
    }
}
// Function for formatted matrix output
void PrintMatrix(double* pMatrix, int RowCount, int ColCount)
{
    int i, j; // Loop variables
    for (i = 0; i < RowCount; i++)
    {
        for (j = 0; j < ColCount; j++)
            printf("%7.4f ", pMatrix[i * RowCount + j]);
        printf("\n");
    }
}
// Function for matrix multiplication
void SerialResultCalculation(double* pAMatrix, double* pBMatrix, double* pCMatrix, int Size)
{
    int i, j, k; // Loop variables
    for (i = 0; i < Size; i++)
    {
        for (j = 0; j < Size; j++)
            for (k = 0; k < Size; k++)
                pCMatrix[i * Size + j] += pAMatrix[i * Size + k] * pBMatrix[k * Size + j];
    }
}
// Function for computational process termination
void ProcessTermination(double* pAMatrix, double* pBMatrix, double* pCMatrix)
{
    delete[] pAMatrix;
    delete[] pBMatrix;
    delete[] pCMatrix;
}
void ParallelResultCalculation(double* pAMatrix, double* pBMatrix, double* pCMatrix, int Size)
{
    int ThreadNum = 4;
    int GridSize = int(sqrt((double)ThreadNum));
    int BlockSize = Size / GridSize;
    omp_set_num_threads(ThreadNum);
#pragma omp parallel
    {
        int ThreadID = omp_get_thread_num();
        int RowIndex = ThreadID / GridSize;
        int ColIndex = ThreadID % GridSize;
        for (int iter = 0; iter < GridSize; iter++)
        {
            for (int i = RowIndex * BlockSize; i < (RowIndex + 1) * BlockSize; i++)
                for (int j = ColIndex * BlockSize; j < (ColIndex + 1) * BlockSize; j++)
                    for (int k = iter * BlockSize; k < (iter + 1) * BlockSize; k++)
                        pCMatrix[i * Size + j] += pAMatrix[i * Size + k] * pBMatrix[k * Size + j];
        }
    } // pragma omp parallel
}
void TestResult(double* pAMatrix, double* pBMatrix, double* pCMatrix, int Size)
{
    double* pSerialResult; // Result matrix of serial multiplication
    double Accuracy = 1.e-6; // Comparison accuracy
    int equal = 0; // =1, if the matrices are not equal
    int i; // Loop variable
    pSerialResult = new double[Size * Size];
    for (i = 0; i < Size * Size; i++)
    {
        pSerialResult[i] = 0;
    }
    SerialResultCalculation(pAMatrix, pBMatrix, pSerialResult, Size);
    for (i = 0; i < Size * Size; i++)
    {
        if (fabs(pSerialResult[i] - pCMatrix[i]) >= Accuracy)
            equal = 1;
    }
    if (equal == 1)
        printf("The results of serial and parallel algorithms "
               "are NOT identical. Check your code.");
    else
        printf("The results of serial and parallel algorithms "
               "are identical.");
    delete[] pSerialResult;
}
// Serial block matrix mutiplication
void OptimalResultCalculation(double* pAMatrix, double* pBMatrix, double* pCMatrix, int Size)
{
    int BlockSize = 250;
    int GridSize = int(Size / double(BlockSize));
    for (int n = 0; n < GridSize; n++)
        for (int m = 0; m < GridSize; m++)
            for (int iter = 0; iter < GridSize; iter++)
                for (int i = n * BlockSize; i < (n + 1) * BlockSize; i++)
                    for (int j = m * BlockSize; j < (m + 1) * BlockSize; j++)
                        for (int k = iter * BlockSize; k < (iter + 1) * BlockSize; k++)
                            pCMatrix[i * Size + j]
                                += pAMatrix[i * Size + k] * pBMatrix[k * Size + j];
}
void ParallelOptimalResultCalculation(
    double* pAMatrix, double* pBMatrix, double* pCMatrix, int Size)
{
    int BlockSize = 250;
    int GridSize = int(Size / double(BlockSize));
    for (int n = 0; n < GridSize; n++)
#pragma omp parallel for
        for (int m = 0; m < GridSize; m++)
            for (int iter = 0; iter < GridSize; iter++)
                for (int i = n * BlockSize; i < (n + 1) * BlockSize; i++)
                    for (int j = m * BlockSize; j < (m + 1) * BlockSize; j++)
                        for (int k = iter * BlockSize; k < (iter + 1) * BlockSize; k++)
                            pCMatrix[i * Size + j]
                                += pAMatrix[i * Size + k] * pBMatrix[k * Size + j];
}
void main()
{
    double* pAMatrix; // The first argument of matrix multiplication
    double* pBMatrix; // The second argument of matrix multiplication
    double* pCMatrix; // The result matrix
    int Size; // Size of matricies
    double start, finish;
    double duration;
    printf("Serial matrix multiplication program\n");
    // Memory allocation and initialization of matrix elements
    ProcessInitialization(pAMatrix, pBMatrix, pCMatrix, Size);
    // Matrix output
    printf("Initial A Matrix \n");
    PrintMatrix(pAMatrix, Size, Size);
    printf("Initial B Matrix \n");
    PrintMatrix(pBMatrix, Size, Size);
    // Matrix multiplication
    start = GetTime();
    SerialResultCalculation(pAMatrix, pBMatrix, pCMatrix, Size);
    finish = GetTime();
    duration = (finish - start) / double(CLOCKS_PER_SEC);
 
    // Printing the result matrix
    printf("\n Result Matrix: \n");
    PrintMatrix(pCMatrix, Size, Size);
    // Printing the time spent by matrix multiplication
    printf("\n Time of execution: %f\n", duration);
    start = GetTime();
    ParallelResultCalculation(pAMatrix, pBMatrix, pCMatrix, Size);
    finish = GetTime();
    duration = finish - start;
    TestResult(pAMatrix, pBMatrix, pCMatrix, Size);
    printf("Time of parallel execution = %f\n", duration);
    start = GetTime();
    OptimalResultCalculation(pAMatrix, pBMatrix, pCMatrix, Size);
    finish = GetTime();
    duration = finish - start;
    // Printing the time spent by matrix multiplication
    printf("\n Time of optimal execution: %f\n", duration);
    start = GetTime();
    ParallelOptimalResultCalculation(pAMatrix, pBMatrix, pCMatrix, Size);
    finish = GetTime();
    duration = finish - start;
    TestResult(pAMatrix, pBMatrix, pCMatrix, Size);
    printf("Time of optimal algorithm parallel execution = %f\n", duration);
    // Computational process termination
    ProcessTermination(pAMatrix, pBMatrix, pCMatrix);
}
up
#include "stdafx.h"
#include <time.h>
#include <omp.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
 
void PrintMatrix(int* pMatrix, int RowCount, int ColCount) {
    int i, j; // Loop variables
    for (i = 0; i<RowCount; i++) {
        for (j = 0; j<ColCount; j++)
            printf("%d ", pMatrix[i*RowCount + j]);
        printf("\n");
    }
}
void DummyDataInitialization(int* pAMatrix, int* pBMatrix, int Size1, int Size2, int Size3, int Size4, int Size5, int Size6)
{
    int i, j, i2, j2; // Loop variables
 
    for (i = 0; i<Size1; i++)
        for (j = 0; j<Size2; j++) {
            pAMatrix[i*Size1 + j] = rand() % 10;
        }
 
    for (i2 = 0; i2<Size3; i2++)
        for (j2 = 0; j2<Size4; j2++) {
            pBMatrix[i2*Size3 + j2] = rand() % 10;
        }
}
void ProcessInitialization(int* &pAMatrix, int* &pBMatrix, int* &pCMatrix, int &Size1, int &Size2, int &Size3, int &Size4, int &Size5, int &Size6)
{
    int Size=0;
    // Setting the size of matricies
        printf("\nvvedite kolichestvo strok matrici A: ");
        scanf("%d", &Size1);
        printf("\nvvedite kolichestvo stolbcov matrici A: ");
        scanf("%d", &Size2);
        printf("\nvvedite kolichestvo strok matrici B: ");
        scanf("%d", &Size3);
        printf("\nvvedite kolichestvo stolbcov matrici B: ");
        scanf("%d", &Size4);
        //  printf("\nChosen matricies' size = %d\n", Size);
    // Memory allocation
    Size5 = Size2;
    Size6 = Size4;
    pAMatrix = new int[Size1*Size2];
    pBMatrix = new int[Size3*Size4];
    pCMatrix = new int[Size5*Size6];
    // Initialization of matrix elements
    DummyDataInitialization(pAMatrix, pBMatrix, Size1, Size2, Size3, Size4, Size5, Size6);
}
 
void ParallelResultCalculation(int* pAMatrix, int* pBMatrix, int* pCMatrix, int Size1, int Size2, int Size3, int Size4, int Size5, int Size6)
{
    int Size = 1;
    int ThreadNum = 4;
    int GridSize = int(sqrt((double)ThreadNum));
    int BlockSize = Size / GridSize;
    omp_set_num_threads(ThreadNum);
#pragma omp parallel 
    {
        int ThreadID = omp_get_thread_num();
        int RowIndex = ThreadID / GridSize;
        int ColIndex = ThreadID%GridSize;
        for (int iter = 0; iter<GridSize; iter++) 
        {
            for (int i = RowIndex*BlockSize; i<(RowIndex + 1)*BlockSize; i++)
                for (int j = ColIndex*BlockSize; j<(ColIndex + 1)*BlockSize; j++)
                    for (int k = iter*BlockSize; k<(iter + 1)*BlockSize; k++)
                        pCMatrix[i*Size + j] += pAMatrix[i*Size1 + k] * pBMatrix[k*Size3 + j];
            printf("Matrica C \n");
            PrintMatrix(pCMatrix, Size5, Size6);
        }
    } // pragma omp parallel
}
 
void main() 
{
    int* pAMatrix; // The first argument of matrix multiplication
    int* pBMatrix; // The second argument of matrix multiplication
    int* pCMatrix; // The result matrix
    int Size1, Size2, Size3, Size4, Size5, Size6; // Size of matricies
    double start, finish;
    double duration;
    // Memory allocation and initialization of matrix elements
    ProcessInitialization(pAMatrix, pBMatrix, pCMatrix, Size1, Size2, Size3, Size4, Size5, Size6);
    // Matrix output
    printf("Matrica A \n");
    PrintMatrix(pAMatrix, Size1, Size2);
    printf("Matrica B \n");
    PrintMatrix(pBMatrix, Size3, Size4);
    ParallelResultCalculation(pAMatrix, pBMatrix, pCMatrix, Size1, Size2, Size3, Size4, Size5, Size6);
}
завтра сдать нужно, помогите пожалуйста)

Решение задачи: «Параллельное умножение матриц»

textual
Листинг программы
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <time.h>
 
using namespace std;
int main()
{
    int n, m, q, i, j;
    srand(time(NULL));
    clock_t time_test;
    cout << "Enter cols count in matrix A and rows count in matrix B: ";
    cin >> n;
    cout << "Enter rows count in matrix A: ";
    cin >> m;
    cout << "Enter cols count in matrix B: ";
    cin >> q;
    int **aArr = new int *[m];
    for (i = 0; i < m; i++)
        aArr[i] = new int[n];
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            aArr[i][j] = rand() % 20 + 1;
        }
    }
    if (n <= 15 && q <= 15)
    {
        cout << "Matrix A: " << endl;
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
                cout << setw(5) << aArr[i][j];
            cout << endl;
        }
    }
    int **bArr = new int *[n];
    for (i = 0; i < n; i++)
    {
        bArr[i] = new int[q];
        for (j = 0; j < q; j++)
        {
            bArr[i][j] = rand() % 20 + 1;;
        }
    }
    if (n <= 15 && q <= 15)
    {
        cout << "Matrix B: " << endl;
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < q; j++)
                cout << setw(5) << bArr[i][j];
            cout << endl;
        }
    }
    int **cArr = new int *[m];
    for (i = 0; i < m; i++)
        cArr[i] = new int[q];
    cout << "Please, wait..." << endl;
    time_test = clock();
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < q; j++)
        {
            cArr[i][j] = 0;
            for (int v = 0; v < n; v++)
            {
                cArr[i][j] += aArr[i][v] * bArr[v][j];
            }
        }
    }
    time_test = clock() - time_test;
    cout << "-----Success!-----" << endl << "Time: " << (double)time_test / CLOCKS_PER_SEC << " seconds" <<endl;
    if (n <= 15 && q <= 15)
    {
        cout << "Matrix C: " << endl;
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < q; j++)
                cout << setw(5) << cArr[i][j];
            cout << endl;
        }
    }
    getchar(); getchar();
    return 0;
}

Объяснение кода листинга программы

В данном коде реализуется параллельное умножение матриц. Ниже представлен список действий, выполняемых в коде:

  1. Ввод от пользователя размеров матриц A и B.
  2. Создание динамических массивов для хранения матрицы A и B.
  3. Заполнение матрицы A случайными числами от 1 до 20.
  4. Вывод матрицы A на экран.
  5. Создание динамического массива для хранения матрицы C.
  6. Заполнение матрицы C нулями.
  7. Выполнение параллельного умножения матриц A и B, используя матрицу C.
  8. Вывод матрицы C на экран.
  9. Ожидание ввода от пользователя для выхода из программы.
  10. Возврат 0, указывающий на успешное завершение программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.182 из 5
Похожие ответы