Autre session d'optimisation

This commit is contained in:
Timothée Leclaire-Fournier 2024-01-21 12:19:40 -05:00
parent b0c940f633
commit 53a8a048d9
3 changed files with 86 additions and 75 deletions

View File

@ -1,11 +1,9 @@
#include "GOLTeamH.h" #include "GOLTeamH.h"
GOLTeamH::GOLTeamH()
: mParsedRule{}
//Inlining des acesseur dans GOLTeam.h {
}
//! \brief Accesseurs retournant des informations générales sur la //! \brief Accesseurs retournant des informations générales sur la
//! simulation en cours. //! simulation en cours.
@ -146,7 +144,7 @@ bool GOLTeamH::setRule(std::string const& rule)
{ {
mRule = rule; mRule = rule;
bool firstPart{ true }; bool firstPart{ true };
uint16_t parsedRuleRevive{}, parsedRuleSurvive{}; uint32_t parsedRule{};
// On vérifie que la chaine de charactères contient un B au début. // On vérifie que la chaine de charactères contient un B au début.
// 5 = taille minimale // 5 = taille minimale
@ -160,9 +158,9 @@ bool GOLTeamH::setRule(std::string const& rule)
// Si c'est un chiffre, on continue en enregistrant la valeur. // Si c'est un chiffre, on continue en enregistrant la valeur.
if (opt.has_value()) { if (opt.has_value()) {
if (firstPart) if (firstPart)
parsedRuleRevive |= 1u << opt.value(); parsedRule |= 1u << opt.value();
else else
parsedRuleSurvive |= 1u << opt.value(); parsedRule |= 1u << (opt.value() + 16);
continue; continue;
} }
@ -179,8 +177,7 @@ bool GOLTeamH::setRule(std::string const& rule)
return false; return false;
} }
mParsedRuleRevive = parsedRuleRevive; mParsedRule |= parsedRule;
mParsedRuleSurvive = parsedRuleSurvive;
return true; return true;
} }
@ -384,21 +381,17 @@ void GOLTeamH::processOneStep()
if (mBorderManagement == GOL::BorderManagement::foreverDead) { if (mBorderManagement == GOL::BorderManagement::foreverDead) {
size_t aliveCount{}; size_t aliveCount{};
size_t offset{ width() + 2 }; size_t offset{ width() + 2 };
auto* ptrGrid{ &grid[0] }; // Pointeur qui se promène en mémoire. auto width{ mData.width() }, height{ mData.height() };
auto* const ptrGridInt{ &intGrid[0] }; // Pointeur statique pour des calculs.
for (size_t i{}; i < mData.realSize() - offset - 1; ++i) { // Index commence à la première case qui n'est pas dans le border
auto* ptrGridInt{ &intGrid[width + 3] }; // Pointeur du tableau intermédiaire.
auto* ptrGrid{ &grid[width + 3] }; // Pointeur qui se promène en mémoire.
if (mData.isInBorder(i)) { for (size_t j{}; j < height; ++j) {
ptrGrid++; for (size_t i{}; i < width; ++i) {
continue;
}
aliveCount = 0; aliveCount = 0;
// On prend avantage du fait que GOL::State::alive = 1 et donc
// on retire des branches if.
// Top // Top
ptrGrid -= offset + 1; ptrGrid -= offset + 1;
aliveCount += static_cast<uint8_t> (*ptrGrid); aliveCount += static_cast<uint8_t> (*ptrGrid);
@ -424,16 +417,25 @@ void GOLTeamH::processOneStep()
// On retourne à une place plus loin qu'à l'origine. // On retourne à une place plus loin qu'à l'origine.
ptrGrid -= offset; ptrGrid -= offset;
ptrGridInt++;
// On prend avantage du fait que GOL::State::alive = 1. // On prend avantage du fait que GOL::State::alive = 1.
// //
// On évite aussi d'utiliser l'opérateur []. En profilant, nous avons vu un // On évite aussi d'utiliser l'opérateur []. En profilant, nous avons vu un
// impact de performance de ~5%. // impact de performance de ~5%.
if (*(ptrGrid - 1) == GOL::State::alive) //
*(ptrGridInt + i) = static_cast<GOL::State>(static_cast<bool>(mParsedRuleSurvive & (1u << aliveCount))); // On accède à la bonne partie des bits et on compare si le bit de survie/réanimation est
else // présent. Voir GOLTeamH.cpp pour plus de détails.
*(ptrGridInt + i) = static_cast<GOL::State>(static_cast<bool>(mParsedRuleRevive & (1u << aliveCount))); *(ptrGridInt - 1) = static_cast<GOL::State>(
static_cast<bool>(
(mParsedRule >> static_cast<bool>(*(ptrGrid - 1)) * 16) & (1u << aliveCount)
)
);
}
// On saute le border
ptrGrid += 2;
ptrGridInt += 2;
} }
ptrGrid = nullptr; ptrGrid = nullptr;
@ -483,18 +485,15 @@ void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const
return; return;
auto s_ptr = buffer; auto s_ptr = buffer;
auto e_ptr = &buffer[buffer_size];
auto& grid = mData.data(); auto& grid = mData.data();
auto width{ mData.width() }, height{ mData.height() };
auto* ptrGrid{ &grid[width + 3] }; // Pointeur qui se promène en mémoire.
// On itère sur chaque éléments du tableau et on associe la couleur. // On itère sur chaque éléments du tableau et on associe la couleur.
for (size_t index{ width() + 2 }; // On ignore la ligne du bas. for (size_t j{}; j < height; ++j) {
index < (width() + 2) * (height() + 1); // On ignore la ligne du haut. for (size_t i{}; i < width; ++i) {
index++) { auto var = static_cast<uint8_t>(*ptrGrid);
if (mData.isInBorder(index))
continue;
auto var = static_cast<uint8_t>(grid[index]);
*s_ptr &= 0; // Clear *s_ptr &= 0; // Clear
*s_ptr |= MAX_ALPHA << 24; // Alpha = 255 *s_ptr |= MAX_ALPHA << 24; // Alpha = 255
@ -508,6 +507,9 @@ void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const
*s_ptr |= mDeadColor.blue * (1 - var); *s_ptr |= mDeadColor.blue * (1 - var);
s_ptr++; s_ptr++;
ptrGrid++;
}
ptrGrid += 2;
} }
} }

View File

@ -12,6 +12,8 @@ constexpr unsigned char MAX_ALPHA = 255;
class GOLTeamH : public GOL class GOLTeamH : public GOL
{ {
public: public:
GOLTeamH();
// inline puisque trivial. // inline puisque trivial.
size_t width() const override { return mData.width(); } size_t width() const override { return mData.width(); }
size_t height() const override { return mData.height(); } size_t height() const override { return mData.height(); }
@ -43,7 +45,14 @@ private:
// On utilise un bitset qui contient les règles de chaque nombre. // On utilise un bitset qui contient les règles de chaque nombre.
// On n'utilise pas std::bitset pour des raisons de performance. // On n'utilise pas std::bitset pour des raisons de performance.
uint16_t mParsedRuleRevive, mParsedRuleSurvive; //
// Le premier 8 bits (à gauche) est celui de la règle de survie alors
// qu'à droite nous avons la règle de réanimation.
// 0000000111000111 0000000110011001
// ^^^^^^^ ^^^^^^^
// Bits non utilisés
//
uint32_t mParsedRule;
GridTeamH mData; GridTeamH mData;
Color mDeadColor, mAliveColor; Color mDeadColor, mAliveColor;

View File

@ -83,7 +83,7 @@ private:
}; };
// Attention: performance terrible si utilisation. Seulement lorsque vitesse // Attention: performance terrible si utilisation. Seulement lorsque vitesse
// n'est pas demandée. // n'est pas demandée, donc pas dans la boucle principale.
inline bool GridTeamH::isInBorder(size_t index) const inline bool GridTeamH::isInBorder(size_t index) const
{ {
return(index % (mWidth + 2) < 1 return(index % (mWidth + 2) < 1