Test wurde für kleinere Matrizen angepasst -> Komponentenweiser Vergleich
This commit is contained in:
parent
6d084c7d88
commit
89cc39c906
@ -3,6 +3,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
|
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ void generateRandomMatrices(int n,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Serielle Multiplikation
|
// Seriell
|
||||||
|
|
||||||
std::vector<std::vector<double>> matmul_serial(const std::vector<std::vector<double>>& A,
|
std::vector<std::vector<double>> matmul_serial(const std::vector<std::vector<double>>& A,
|
||||||
const std::vector<std::vector<double>>& B)
|
const std::vector<std::vector<double>>& B)
|
||||||
@ -51,9 +52,9 @@ std::vector<std::vector<double>> matmul_serial(const std::vector<std::vector<dou
|
|||||||
|
|
||||||
// Parallele Zeilenzerlegung
|
// Parallele Zeilenzerlegung
|
||||||
|
|
||||||
std::vector<std::vector<double>> matmul_row_parallel(const std::vector<std::vector<double>>& A,
|
std::vector<std::vector<double>> matmul_parallel_rows(const std::vector<std::vector<double>>& A,
|
||||||
const std::vector<std::vector<double>>& B,
|
const std::vector<std::vector<double>>& B,
|
||||||
int numThreads)
|
int numThreads)
|
||||||
{
|
{
|
||||||
int n = A.size();
|
int n = A.size();
|
||||||
int m = B[0].size();
|
int m = B[0].size();
|
||||||
@ -61,13 +62,19 @@ std::vector<std::vector<double>> matmul_row_parallel(const std::vector<std::vect
|
|||||||
|
|
||||||
std::vector<std::vector<double>> C(n, std::vector<double>(m, 0.0));
|
std::vector<std::vector<double>> C(n, std::vector<double>(m, 0.0));
|
||||||
|
|
||||||
omp_set_num_threads(numThreads);
|
#pragma omp parallel for num_threads(numThreads)
|
||||||
|
|
||||||
#pragma omp parallel for
|
|
||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
std::vector<double> row(m, 0.0);
|
||||||
for (int j = 0; j < m; ++j)
|
for (int j = 0; j < m; ++j)
|
||||||
|
{
|
||||||
|
double sum = 0.0;
|
||||||
for (int k = 0; k < p; ++k)
|
for (int k = 0; k < p; ++k)
|
||||||
C[i][j] += A[i][k] * B[k][j];
|
sum += A[i][k] * B[k][j]; //verhindert überschreibuung
|
||||||
|
row[j] = sum;
|
||||||
|
}
|
||||||
|
C[i] = row;
|
||||||
|
}
|
||||||
|
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
@ -75,9 +82,9 @@ std::vector<std::vector<double>> matmul_row_parallel(const std::vector<std::vect
|
|||||||
|
|
||||||
// Parallele Spaltenzerlegung
|
// Parallele Spaltenzerlegung
|
||||||
|
|
||||||
std::vector<std::vector<double>> matmul_col_parallel(const std::vector<std::vector<double>>& A,
|
std::vector<std::vector<double>> matmul_parallel_cols(const std::vector<std::vector<double>>& A,
|
||||||
const std::vector<std::vector<double>>& B,
|
const std::vector<std::vector<double>>& B,
|
||||||
int numThreads)
|
int numThreads)
|
||||||
{
|
{
|
||||||
int n = A.size();
|
int n = A.size();
|
||||||
int m = B[0].size();
|
int m = B[0].size();
|
||||||
@ -85,24 +92,28 @@ std::vector<std::vector<double>> matmul_col_parallel(const std::vector<std::vect
|
|||||||
|
|
||||||
std::vector<std::vector<double>> C(n, std::vector<double>(m, 0.0));
|
std::vector<std::vector<double>> C(n, std::vector<double>(m, 0.0));
|
||||||
|
|
||||||
omp_set_num_threads(numThreads);
|
#pragma omp parallel for num_threads(numThreads)
|
||||||
|
|
||||||
#pragma omp parallel for
|
|
||||||
for (int j = 0; j < m; ++j)
|
for (int j = 0; j < m; ++j)
|
||||||
|
{
|
||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
double sum = 0.0;
|
||||||
for (int k = 0; k < p; ++k)
|
for (int k = 0; k < p; ++k)
|
||||||
C[i][j] += A[i][k] * B[k][j];
|
sum += A[i][k] * B[k][j]; //Zwischengepeichert
|
||||||
|
C[i][j] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parallele Blockzerlegung
|
// Blockzerlegung
|
||||||
|
|
||||||
std::vector<std::vector<double>> matmul_block_parallel(const std::vector<std::vector<double>>& A,
|
std::vector<std::vector<double>> matmul_block(const std::vector<std::vector<double>>& A,
|
||||||
const std::vector<std::vector<double>>& B,
|
const std::vector<std::vector<double>>& B,
|
||||||
int blockSize,
|
int blockSize,
|
||||||
int numThreads)
|
int numThreads)
|
||||||
{
|
{
|
||||||
int n = A.size();
|
int n = A.size();
|
||||||
int m = B[0].size();
|
int m = B[0].size();
|
||||||
@ -110,54 +121,118 @@ std::vector<std::vector<double>> matmul_block_parallel(const std::vector<std::ve
|
|||||||
|
|
||||||
std::vector<std::vector<double>> C(n, std::vector<double>(m, 0.0));
|
std::vector<std::vector<double>> C(n, std::vector<double>(m, 0.0));
|
||||||
|
|
||||||
omp_set_num_threads(numThreads);
|
#pragma omp parallel for collapse(2) num_threads(numThreads)
|
||||||
|
|
||||||
#pragma omp parallel for collapse(2)
|
|
||||||
for (int ii = 0; ii < n; ii += blockSize)
|
for (int ii = 0; ii < n; ii += blockSize)
|
||||||
for (int jj = 0; jj < m; jj += blockSize)
|
for (int jj = 0; jj < m; jj += blockSize)
|
||||||
|
{
|
||||||
for (int i = ii; i < std::min(ii + blockSize, n); ++i)
|
for (int i = ii; i < std::min(ii + blockSize, n); ++i)
|
||||||
for (int j = jj; j < std::min(jj + blockSize, m); ++j)
|
for (int j = jj; j < std::min(jj + blockSize, m); ++j)
|
||||||
|
{
|
||||||
|
double sum = 0.0;
|
||||||
for (int k = 0; k < p; ++k)
|
for (int k = 0; k < p; ++k)
|
||||||
C[i][j] += A[i][k] * B[k][j];
|
sum += A[i][k] * B[k][j];
|
||||||
|
C[i][j] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Main
|
// Matrix ausgeben
|
||||||
|
|
||||||
|
void printMatrix(const std::vector<std::vector<double>>& M, const std::string& name)
|
||||||
|
{
|
||||||
|
std::cout << name << " (" << M.size() << "x" << (M.empty() ? 0 : M[0].size()) << "):\n";
|
||||||
|
for (const auto& row : M)
|
||||||
|
{
|
||||||
|
for (double val : row)
|
||||||
|
std::cout << val << "\t";
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Matrix Vergleich (Komponentenweise)
|
||||||
|
bool compareMatrices(const std::vector<std::vector<double>>& A,
|
||||||
|
const std::vector<std::vector<double>>& B)
|
||||||
|
{
|
||||||
|
if (A.size() != B.size() || A[0].size() != B[0].size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < A.size(); ++i)
|
||||||
|
for (size_t j = 0; j < A[0].size(); ++j)
|
||||||
|
if (std::abs(A[i][j] - B[i][j]) > 1e-9)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
int N = 500; // Matrixgröße anpassen
|
int N = 4; // für Ausgabe kleiner Matrizen <5
|
||||||
int numThreads = 4; // Threads für OpenMP
|
int numThreads = omp_get_max_threads();
|
||||||
int blockSize = 64; // Blockgröße für Blockmultiplikation
|
if (numThreads == 0) numThreads = 4;
|
||||||
|
|
||||||
std::vector<std::vector<double>> A, B;
|
std::vector<std::vector<double>> A, B;
|
||||||
generateRandomMatrices(N, A, B);
|
generateRandomMatrices(N, A, B);
|
||||||
|
|
||||||
// Seriell
|
if (N < 5)
|
||||||
|
{
|
||||||
|
printMatrix(A, "Matrix A");
|
||||||
|
printMatrix(B, "Matrix B");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serielle Berechnung
|
||||||
auto start = std::chrono::steady_clock::now();
|
auto start = std::chrono::steady_clock::now();
|
||||||
auto C_serial = matmul_serial(A, B);
|
auto C_serial = matmul_serial(A, B);
|
||||||
auto end = std::chrono::steady_clock::now();
|
auto end = std::chrono::steady_clock::now();
|
||||||
std::cout << "Seriell: " << std::chrono::duration<double>(end-start).count() << " s\n";
|
double timeSerial = std::chrono::duration<double>(end - start).count();
|
||||||
|
std::cout << "Seriell: " << timeSerial << " s\n";
|
||||||
|
|
||||||
|
if (N < 5)
|
||||||
|
printMatrix(C_serial, "C_serial");
|
||||||
|
|
||||||
// Zeilenparallel
|
// Zeilenparallel
|
||||||
start = std::chrono::steady_clock::now();
|
start = std::chrono::steady_clock::now();
|
||||||
auto C_row = matmul_row_parallel(A, B, numThreads);
|
auto C_rows = matmul_parallel_rows(A, B, numThreads);
|
||||||
end = std::chrono::steady_clock::now();
|
end = std::chrono::steady_clock::now();
|
||||||
std::cout << "Zeilenparallel: " << std::chrono::duration<double>(end-start).count() << " s\n";
|
double timeRows = std::chrono::duration<double>(end - start).count();
|
||||||
|
std::cout << "Parallel Zeilen: " << timeRows << " s | "
|
||||||
|
<< (compareMatrices(C_serial, C_rows) ? "Match" : "Mismatch") << "\n";
|
||||||
|
|
||||||
|
if (N < 5)
|
||||||
|
printMatrix(C_rows, "C_rows");
|
||||||
|
|
||||||
// Spaltenparallel
|
// Spaltenparallel
|
||||||
start = std::chrono::steady_clock::now();
|
start = std::chrono::steady_clock::now();
|
||||||
auto C_col = matmul_col_parallel(A, B, numThreads);
|
auto C_cols = matmul_parallel_cols(A, B, numThreads);
|
||||||
end = std::chrono::steady_clock::now();
|
end = std::chrono::steady_clock::now();
|
||||||
std::cout << "Spaltenparallel: " << std::chrono::duration<double>(end-start).count() << " s\n";
|
double timeCols = std::chrono::duration<double>(end - start).count();
|
||||||
|
std::cout << "Parallel Spalten: " << timeCols << " s | "
|
||||||
|
<< (compareMatrices(C_serial, C_cols) ? "Match" : "Mismatch") << "\n";
|
||||||
|
|
||||||
|
if (N < 5)
|
||||||
|
printMatrix(C_cols, "C_cols");
|
||||||
|
|
||||||
// Blockparallel
|
// Blockparallel
|
||||||
|
int blockSize = 2; // für kleine N passend
|
||||||
start = std::chrono::steady_clock::now();
|
start = std::chrono::steady_clock::now();
|
||||||
auto C_block = matmul_block_parallel(A, B, blockSize, numThreads);
|
auto C_block = matmul_block(A, B, blockSize, numThreads);
|
||||||
end = std::chrono::steady_clock::now();
|
end = std::chrono::steady_clock::now();
|
||||||
std::cout << "Blockparallel: " << std::chrono::duration<double>(end-start).count() << " s\n";
|
double timeBlock = std::chrono::duration<double>(end - start).count();
|
||||||
|
std::cout << "Parallel Block (" << blockSize << "x" << blockSize << "): "
|
||||||
|
<< timeBlock << " s | "
|
||||||
|
<< (compareMatrices(C_serial, C_block) ? "Match" : "Mismatch") << "\n";
|
||||||
|
|
||||||
|
if (N < 5)
|
||||||
|
printMatrix(C_block, "C_block");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user