Параллельное умножение матриц - 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;
}
Объяснение кода листинга программы
В данном коде реализуется параллельное умножение матриц. Ниже представлен список действий, выполняемых в коде:
- Ввод от пользователя размеров матриц A и B.
- Создание динамических массивов для хранения матрицы A и B.
- Заполнение матрицы A случайными числами от 1 до 20.
- Вывод матрицы A на экран.
- Создание динамического массива для хранения матрицы C.
- Заполнение матрицы C нулями.
- Выполнение параллельного умножения матриц A и B, используя матрицу C.
- Вывод матрицы C на экран.
- Ожидание ввода от пользователя для выхода из программы.
- Возврат 0, указывающий на успешное завершение программы.