Changed for loop in stencil.hpp to double loop, changed main script structure

This commit is contained in:
elvis
2023-08-24 21:19:23 +02:00
parent 1f2827a100
commit 36eb1c7caf
3 changed files with 151 additions and 61 deletions

4
.gitignore vendored
View File

@ -1,3 +1,7 @@
# Project specific
tests/out_*
build/
# General # General
.DS_Store .DS_Store
.AppleDouble .AppleDouble

145
main.cpp
View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#include <algorithm>
#include <cmath> #include <cmath>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
@ -24,13 +25,6 @@
using namespace std; using namespace std;
using namespace ff; using namespace ff;
char *getOption(char **begin, char **end, const std::string &option) {
char **itr = std::find(begin, end, option);
if (itr != end && ++itr != end)
return *itr;
return nullptr;
}
long long int fastflow(vector<string> images, long long int fastflow(vector<string> images,
vector<pair<int, int>> neighborhood, int iterations, vector<pair<int, int>> neighborhood, int iterations,
std::function<char(std::vector<char>)> f, std::function<char(std::vector<char>)> f,
@ -176,15 +170,19 @@ char gameOfLife(vector<char> in) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int average_max = 5; int average_max = 5;
int iter_for_num_workers = 128;
vector<string> images = { int iter_for_num_workers_images1 = 128;
vector<string> images1 = {
"../tests/empty2x2", "../tests/empty2x2",
"../tests/increasing4x6", "../tests/increasing4x6",
"../tests/increasing300x200", "../tests/increasing300x200",
"../tests/random400x2500", "../tests/random400x2500"
// "../tests/equation", };
// "../tests/equation2"
int iter_for_num_workers_images2 = 8;
vector<string> images2 = {
"../tests/equation",
"../tests/equation2"
}; };
vector<pair<int, int>> neig = {make_pair(-1, 1), make_pair(-1, 0), vector<pair<int, int>> neig = {make_pair(-1, 1), make_pair(-1, 0),
@ -195,7 +193,7 @@ int main(int argc, char *argv[]) {
ofstream csvfile; ofstream csvfile;
csvfile.open("performance.csv"); csvfile.open("performance.csv");
for (std::string image : images) { for (std::string image : images1) {
cout << endl cout << endl
<< "\033[1;31mProcessing: \t" << image << "\033[0m" << endl; << "\033[1;31mProcessing: \t" << image << "\033[0m" << endl;
@ -204,39 +202,37 @@ int main(int argc, char *argv[]) {
csvfile << std::filesystem::file_size(image) << "\n"; csvfile << std::filesystem::file_size(image) << "\n";
csvfile << "\n"; csvfile << "\n";
csvfile << "Number of iterations,1,2,4,8,16\n"; csvfile << "Number of iterations,1,2,4,8,16,32\n";
csvfile << "fastflow:,"; csvfile << "fastflow:,";
cout << "\033[1;31mFastflow\033[0m" << endl; cout << "\033[1;31mFastflow\033[0m" << endl;
for (int iterations : {1, 2, 4, 8, 16}) { for (int iterations : {1, 2, 4, 8, 16, 32}) {
vector<long long int> results; vector<long long int> results;
for (int i = 0; i < average_max; ++i) { for (int i = 0; i < average_max; ++i) {
results.push_back( results.push_back(
fastflow({image}, neig, iterations, &gameOfLife, 0)); fastflow({image}, neig, iterations, &gameOfLife, 0));
} }
csvfile << std::accumulate(results.begin(), results.end(), 0) / csvfile << *std::min_element(results.begin(), results.end())
average_max
<< ","; << ",";
} }
csvfile << "\n"; csvfile << "\n";
csvfile << "stdthread:,"; csvfile << "stdthread:,";
cout << "\033[1;31mStdthread\033[0m" << endl; cout << "\033[1;31mStdthread\033[0m" << endl;
for (int iterations : {1, 2, 4, 8, 16}) { for (int iterations : {1, 2, 4, 8, 16, 32}) {
vector<long long int> results; vector<long long int> results;
for (int i = 0; i < average_max; ++i) { for (int i = 0; i < average_max; ++i) {
results.push_back( results.push_back(
stdthreads({image}, neig, iterations, &gameOfLife, 0)); stdthreads({image}, neig, iterations, &gameOfLife, 0));
} }
csvfile << std::accumulate(results.begin(), results.end(), 0) / csvfile << *std::min_element(results.begin(), results.end())
average_max
<< ","; << ",";
} }
csvfile << "\n"; csvfile << "\n";
// ------------------------------------------------------------------ // // ------------------------------------------------------------------ //
csvfile << "Number of Workers,sequential,fastflow,stdthreads,"; csvfile << "Number of Workers,sequential,fastflow,stdthreads,";
csvfile << "Iterations:," << iter_for_num_workers << "\n"; csvfile << "Iterations:," << iter_for_num_workers_images1 << "\n";
cout << "\033[1;31mDifferent number of workers\033[0m" << endl; cout << "\033[1;31mDifferent number of workers\033[0m" << endl;
int hardware_concurrency = std::thread::hardware_concurrency(); int hardware_concurrency = std::thread::hardware_concurrency();
@ -255,10 +251,9 @@ int main(int argc, char *argv[]) {
vector<long long int> results; vector<long long int> results;
for (int i = 0; i < average_max; ++i) { for (int i = 0; i < average_max; ++i) {
results.push_back(sequential( results.push_back(sequential(
{image}, neig, iter_for_num_workers, &gameOfLife)); {image}, neig, iter_for_num_workers_images1, &gameOfLife));
} }
csvfile << std::accumulate(results.begin(), results.end(), 0) / csvfile << *std::min_element(results.begin(), results.end());
average_max;
} }
csvfile << ","; csvfile << ",";
@ -268,11 +263,10 @@ int main(int argc, char *argv[]) {
vector<long long int> results; vector<long long int> results;
for (int i = 0; i < average_max; ++i) { for (int i = 0; i < average_max; ++i) {
results.push_back(fastflow({image}, neig, results.push_back(fastflow({image}, neig,
iter_for_num_workers, iter_for_num_workers_images1,
&gameOfLife, max_workers)); &gameOfLife, max_workers));
} }
csvfile << std::accumulate(results.begin(), results.end(), 0) / csvfile << *std::min_element(results.begin(), results.end());
average_max;
} }
csvfile << ","; csvfile << ",";
@ -282,11 +276,102 @@ int main(int argc, char *argv[]) {
vector<long long int> results; vector<long long int> results;
for (int i = 0; i < average_max; ++i) { for (int i = 0; i < average_max; ++i) {
results.push_back(stdthreads({image}, neig, results.push_back(stdthreads({image}, neig,
iter_for_num_workers, iter_for_num_workers_images1,
&gameOfLife, max_workers)); &gameOfLife, max_workers));
} }
csvfile << std::accumulate(results.begin(), results.end(), 0) / csvfile << *std::min_element(results.begin(), results.end());
average_max; }
csvfile << "\n";
}
}
for (std::string image : images2) {
cout << endl
<< "\033[1;31mProcessing: \t" << image << "\033[0m" << endl;
csvfile << ",Name,Size(B)\n";
csvfile << "Image," << image << ",";
csvfile << std::filesystem::file_size(image) << "\n";
csvfile << "\n";
csvfile << "Number of iterations,1,2,4,8\n";
csvfile << "fastflow:,";
cout << "\033[1;31mFastflow\033[0m" << endl;
for (int iterations : {1, 2, 4, 8}) {
vector<long long int> results;
for (int i = 0; i < average_max; ++i) {
results.push_back(
fastflow({image}, neig, iterations, &gameOfLife, 0));
}
csvfile << *std::min_element(results.begin(), results.end())
<< ",";
}
csvfile << "\n";
csvfile << "stdthread:,";
cout << "\033[1;31mStdthread\033[0m" << endl;
for (int iterations : {1, 2, 4, 8}) {
vector<long long int> results;
for (int i = 0; i < average_max; ++i) {
results.push_back(
stdthreads({image}, neig, iterations, &gameOfLife, 0));
}
csvfile << *std::min_element(results.begin(), results.end())
<< ",";
}
csvfile << "\n";
// ------------------------------------------------------------------ //
csvfile << "Number of Workers,sequential,fastflow,stdthreads,";
csvfile << "Iterations:," << iter_for_num_workers_images2 << "\n";
cout << "\033[1;31mDifferent number of workers\033[0m" << endl;
int hardware_concurrency = std::thread::hardware_concurrency();
vector<int> list_max_workers = vector<int>();
for (int i = 1; i < hardware_concurrency; i*=2) {
list_max_workers.push_back(i);
}
list_max_workers.push_back(hardware_concurrency);
for (int max_workers : list_max_workers) {
csvfile << max_workers << ",";
if (max_workers == 1) {
cout << "\033[1;31mSequential\033[0m" << endl;
vector<long long int> results;
for (int i = 0; i < average_max; ++i) {
results.push_back(sequential(
{image}, neig, iter_for_num_workers_images2, &gameOfLife));
}
csvfile << *std::min_element(results.begin(), results.end());
}
csvfile << ",";
cout << "\033[1;31mFastflow with " << max_workers
<< " workers\033[0m" << endl;
{
vector<long long int> results;
for (int i = 0; i < average_max; ++i) {
results.push_back(fastflow({image}, neig,
iter_for_num_workers_images2,
&gameOfLife, max_workers));
}
csvfile << *std::min_element(results.begin(), results.end());
}
csvfile << ",";
cout << "\033[1;31mStdthread with " << max_workers
<< " workers\033[0m" << endl;
{
vector<long long int> results;
for (int i = 0; i < average_max; ++i) {
results.push_back(stdthreads({image}, neig,
iter_for_num_workers_images2,
&gameOfLife, max_workers));
}
csvfile << *std::min_element(results.begin(), results.end());
} }
csvfile << "\n"; csvfile << "\n";
} }

View File

@ -138,7 +138,7 @@ void Stencil<T>::stdthread(
for (auto result : *ResultsVector) { for (auto result : *ResultsVector) {
Task<T> *task = result.get(); Task<T> *task = result.get();
int niter = Iterations; int niter = Iterations;
int delta = (task->Rows * task->Cols) / MaxThreads; int delta = task->Rows / MaxThreads;
std::vector<std::vector<T>> *arena = new std::vector<std::vector<T>>(0); std::vector<std::vector<T>> *arena = new std::vector<std::vector<T>>(0);
*arena = *(task->VectorData); // copy all from VectorData *arena = *(task->VectorData); // copy all from VectorData
@ -146,9 +146,30 @@ void Stencil<T>::stdthread(
while (niter > 0) { while (niter > 0) {
for (int l = 0; l < MaxThreads - 1; ++l) { for (int l = 0; l < MaxThreads - 1; ++l) {
thread_pool.addJob([&, l, delta] { thread_pool.addJob([&, l, delta] {
for (int k = l * delta; k < (l + 1) * delta; ++k) { for (int x = l * delta; x < (l+1) * delta; ++x) {
int x = k / task->Cols; for (int y = 0; y < task->Cols; ++y) {
int y = k % task->Cols; if (x < Borders[1] || x >= task->Rows - Borders[3] ||
y < Borders[0] || y >= task->Cols - Borders[2]) {
continue;
}
std::vector<T> n;
n.resize(Neighborhood.size());
std::transform(
Neighborhood.begin(), Neighborhood.end(),
n.begin(),
[&task, x, y](std::pair<int, int> e) {
return (*task->VectorData)[x + e.second]
[y + e.first];
});
(*arena)[x][y] = Convolution(n);
}
}
});
}
thread_pool.addJob([&, delta, MaxThreads] {
for (int x = (MaxThreads - 1) * delta;
x < task->Rows; ++x) {
for (int y = 0; y < task->Cols; ++y) {
if (x < Borders[1] || x >= task->Rows - Borders[3] || if (x < Borders[1] || x >= task->Rows - Borders[3] ||
y < Borders[0] || y >= task->Cols - Borders[2]) { y < Borders[0] || y >= task->Cols - Borders[2]) {
continue; continue;
@ -158,31 +179,11 @@ void Stencil<T>::stdthread(
std::transform( std::transform(
Neighborhood.begin(), Neighborhood.end(), n.begin(), Neighborhood.begin(), Neighborhood.end(), n.begin(),
[&task, x, y](std::pair<int, int> e) { [&task, x, y](std::pair<int, int> e) {
return (*task->VectorData)[x + e.second] return (
[y + e.first]; *task->VectorData)[x + e.second][y + e.first];
}); });
(*arena)[x][y] = Convolution(n); (*arena)[x][y] = Convolution(n);
} }
});
}
thread_pool.addJob([&, delta, MaxThreads] {
for (int k = (MaxThreads - 1) * delta;
k < task->Cols * task->Rows; ++k) {
int x = k / task->Cols;
int y = k % task->Cols;
if (x < Borders[1] || x >= task->Rows - Borders[3] ||
y < Borders[0] || y >= task->Cols - Borders[2]) {
continue;
}
std::vector<T> n;
n.resize(Neighborhood.size());
std::transform(
Neighborhood.begin(), Neighborhood.end(), n.begin(),
[&task, x, y](std::pair<int, int> e) {
return (
*task->VectorData)[x + e.second][y + e.first];
});
(*arena)[x][y] = Convolution(n);
} }
}); });
thread_pool.waitEnd(); thread_pool.waitEnd();
@ -250,13 +251,12 @@ template <typename T> Task<T> *Stencil<T>::svc_helper(Task<T> *task) {
while (niter > 0) { while (niter > 0) {
parallel_for( parallel_for(
0, task->Rows * task->Cols, 0, task->Rows,
[&](const int k) { [&](const int x) {
int x = k / task->Cols; for (int y = 0; y < task->Cols; ++y) {
int y = k % task->Cols;
if (x < Borders[1] || x >= task->Rows - Borders[3] || if (x < Borders[1] || x >= task->Rows - Borders[3] ||
y < Borders[0] || y >= task->Cols - Borders[2]) { y < Borders[0] || y >= task->Cols - Borders[2]) {
return; continue;
} }
std::vector<T> n; std::vector<T> n;
n.resize(Neighborhood.size()); n.resize(Neighborhood.size());
@ -266,6 +266,7 @@ template <typename T> Task<T> *Stencil<T>::svc_helper(Task<T> *task) {
return (*task->VectorData)[x + e.second][y + e.first]; return (*task->VectorData)[x + e.second][y + e.first];
}); });
(*arena)[x][y] = Convolution(n); (*arena)[x][y] = Convolution(n);
}
}, },
MaxWorkers); MaxWorkers);
std::swap(task->VectorData, arena); std::swap(task->VectorData, arena);