EliasFarhan/NekoEngine

Observation étrange [Oleg].

Closed this issue · 2 comments

J'ai commencé à faire des benchmarks pour regarder ce qui affecte la performance de l'accés à la FixedMap.
J'ai remarqué que commenter tout le code en rapport avec neko_assert, que NEKO_ASSERT soit défini ou pas, améliorait la vitesse d'une ou deux 100aines de nanosecondes.

Pour vérifier donc, je me suis ammusé à commenter tout le code neko_assert se trouvant dans les custom allocators et j'ai vu également une augmentation de la performance de manière consistente dans la fonction que je profilais.
Le mystère est que dans la fonction que je profile (l'accès à la map) n'a pas du tout d'appels vers du code de custom allocator.

inline Value& operator[](const Key& key)
{
        const auto hash = xxh::xxhash<HASH_SIZE>(&key, 1);
        auto it = std::find_if(Begin(), End(), [hash](const InternalPair p) { return p.first == hash; });
        return it->second;
}

...
private:
    std::pair<xxh::hash<64>, Value>* begin_ = nullptr;
    std::pair<xxh::hash<64>, Value>* end_ = nullptr;
    Allocator& allocator_;

inline Iterator Begin() const
{
        return Iterator{begin_};
}
inline Iterator End() const
{
        return Iterator{end_};
}

...
class Iterator
{
    Iterator(std::pair<xxh::hash<64>, Value>* ptr) : ptr_(ptr){}
private:
    std::pair<xxh::hash<64>, Value>* ptr_;
}

On vois qu'à aucun moment le code de la fonction ne touche l'allocator et pourtant, il y a une différence de 100ns avec ou sans le code de neko_assert dans le code des custom allocators.

Before:
BM_FixedMap_Access                           3818 ns         3818 ns       183888

After: 
BM_FixedMap_Access                           3721 ns         3721 ns       188615

Vous avez une idée pourquoi?

Le range est à une taille fixe de 128 élements.

Ouaip, j'avais pas mis trop de détails au cas ou c'était qqch d'évident mais ouais ok voilà une série un peu plus détaillée:

Voici les résultats. J'ai lancé le meme benchmark 20 fois d'affilée, 10 pour un average avant d'enlever neko_assert et 10 après les avoir enlevé:

results

Bon il y a une grande différence dans BM_FixedMap_InitFillOutAndClear ce qui est normal étant donné qu'à l'Init d'une FixedMap on passe par le code des allocateurs justement donc c'est normal.

Par contre c'est intéressant de voir que même la std::unordered_map change de performance.
Je pense que c'est moins dû aux asserts et plus au fait qu'avec moins de code, il y a plus de mémoire qui peut être utilisée pour le code existant peut être?
Ou alors c'est juste du hasard. Ou alors c'est dû à un détail technique obscure du hardware.

Je mets en bas le code source des fichiers au cas oú mais ouais, c'était plus par curiosité qu'autre chose, la différence n'est pas suffisament significative dans le cardre de l'optimisation des FixedMap.

results.zip
src.zip