Параллельное умножение матриц - 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, указывающий на успешное завершение программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д