Commit 64d23777 authored by Thomas Steinreiter's avatar Thomas Steinreiter
Browse files

perfomance improvements

parent 3b77dee3
...@@ -12,47 +12,56 @@ ...@@ -12,47 +12,56 @@
#include "Tile.hpp" #include "Tile.hpp"
#include "Util.hpp" #include "Util.hpp"
void MpiWireworld::processCell(std::size_t x, std::size_t y) { void MpiWireworld::processArea(Coord start, Size size) {
const auto& _model = _tile.model(); auto& _model = _tile.model();
const auto modelWidth = _tile.modelWidth();
auto& _nextModel = _tile.nextModel(); auto& _nextModel = _tile.nextModel();
const auto currentState = _model[y * modelWidth + x]; const auto modelWidth = _tile.modelWidth();
_nextModel[y * modelWidth + x] = [&]() { // std::size_t is unsigned. modulo arithmetics is used for calculating the
switch (currentState) { // index
case State::ElectronHead: const std::size_t leftOffset = -1;
return State::ElectronTail; const std::size_t rightOffset = 1;
break; const std::size_t downOffset = modelWidth;
case State::ElectronTail: const std::size_t upOffset = -downOffset;
return State::Conductor;
break; for (std::size_t y{start.Y}; y < start.Y + size.Rows; ++y) {
case State::Conductor: { for (std::size_t x{start.X}; x < start.X + size.Cols; ++x) {
const auto idx = [&](std::size_t y, std::size_t x) { const auto idx = y * modelWidth + x;
return y * modelWidth + x;
}; const auto currentState = _model[idx];
const std::array<State, 9> mooreNeighborhood = { _nextModel[idx] = [&]() {
_model[idx(y - 1, x - 1)], // switch (currentState) {
_model[idx(y + 0, x - 1)], // case State::ElectronHead:
_model[idx(y + 1, x - 1)], // return State::ElectronTail;
_model[idx(y - 1, x + 0)], // break;
_model[idx(y + 1, x + 0)], // case State::ElectronTail:
_model[idx(y - 1, x + 1)], // return State::Conductor;
_model[idx(y + 0, x + 1)], // break;
_model[idx(y + 1, x + 1)] // case State::Conductor: {
}; const auto isHead = [&](std::size_t idx) {
return _model[idx] == State::ElectronHead ? 1 : 0;
const auto headCount = };
std::count(std::begin(mooreNeighborhood), const auto headCount =
std::end(mooreNeighborhood), State::ElectronHead); isHead(idx + leftOffset + upOffset) + //
isHead(idx + upOffset) + //
return (1 == headCount || headCount == 2) ? State::ElectronHead isHead(idx + rightOffset + upOffset) + //
: State::Conductor; isHead(idx + leftOffset) + //
} break; isHead(idx + rightOffset) + //
default: isHead(idx + leftOffset + downOffset) + //
return currentState; isHead(idx + downOffset) + //
break; isHead(idx + rightOffset + downOffset); //
return (1 == headCount || headCount == 2)
? State::ElectronHead
: State::Conductor;
} break;
default:
return currentState;
break;
}
}();
} }
}(); }
} }
MpiWireworld::MpiWireworld(const MpiEnvironment& env, const Configuration& cfg) MpiWireworld::MpiWireworld(const MpiEnvironment& env, const Configuration& cfg)
...@@ -79,31 +88,21 @@ void MpiWireworld::simulateStep() { ...@@ -79,31 +88,21 @@ void MpiWireworld::simulateStep() {
/// border area /// border area
// top // top
for (std::size_t x{1}; x <= _tileSize.Cols; ++x) { processArea({1, 1}, {_tileSize.Cols, 1});
const auto y = 1;
processCell(x, y);
}
// left and right // left and right
for (std::size_t y{2}; y < _tileSize.Rows; ++y) { processArea({1, 2}, {1, _tileSize.Rows - 2});
const auto x1 = 1; processArea({_tileSize.Cols, 2}, {1, _tileSize.Rows - 2});
const auto x2 = _tileSize.Cols;
processCell(x1, y);
processCell(x2, y);
}
// bottom // bottom
for (std::size_t x{1}; x <= _tileSize.Cols; ++x) { processArea({1, _tileSize.Rows}, {_tileSize.Cols, 1});
const auto y = _tileSize.Rows;
processCell(x, y);
}
// start communication of border while processing the core // start communication of border while processing the core
auto req = _comm.AsyncCommunicate(_nextModel); auto req = _comm.AsyncCommunicate(_nextModel);
/// core /// core
for (std::size_t y{2}; y < _tileSize.Rows; ++y) { processArea({2, 2}, {_tileSize.Cols - 2, _tileSize.Rows - 2});
for (std::size_t x{2}; x < _tileSize.Cols; ++x) { processCell(x, y); }
}
req.Wait(); req.Wait();
std::swap(_model, _nextModel); std::swap(_model, _nextModel);
......
...@@ -13,7 +13,7 @@ class MpiWireworld { ...@@ -13,7 +13,7 @@ class MpiWireworld {
Tile _tile; Tile _tile;
Communicator _comm; Communicator _comm;
void processCell(std::size_t x, std::size_t y); void processArea(Coord start, Size size);
public: public:
MpiWireworld(const MpiEnvironment& env, const Configuration& cfg); MpiWireworld(const MpiEnvironment& env, const Configuration& cfg);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment