Hi

Any feedback regarding this patch ?

François

On 24/07/2023 13:02, François Dumont wrote:
libstdc++: [_Hashtable] Make more use of insertion hint


    When inserting an element into an empty bucket we currently insert the new node     after the before-begin node so in first position. The drawback of doing this is     that we are forced to update the bucket that was containing this before-begin     node to point to the newly inserted node. To do so we need at best to do a modulo
    to find this bucket and when hash code is not cached also compute it.

    To avoid this side effect it is better to insert after the last node. Adding     a member to keep track of this last node would be an abi breaking change. Still we     can ask the user to maintain and provide this last node as an insertion hint.

    Adapt range insertion methods to try to detect the last node and then use it as
    the insertion hint.

    libstdc++-v3/ChangeLog:

            * include/bits/hashtable_policy.h:
            (_Insert_base::try_emplace): Adapt to use hint.
            (_Insert_base::_M_insert_range): Try to detect container last node and use it
            as hint for insertions.
            (_Hash_code_base::_M_hash_code(const _Hash&, const _Hash_node_value<>&)): Remove.             (_Hash_code_base::_M_hash_code<_H2>(const _H2&, const _Hash_node_value<>&)): Remove.
            * include/bits/hashtable.h
            (_Hashtable<>::_M_insert_bucket_begin): Add hint parameter and use it when inserting
            into an empty bucket if hint is the last container node.
            (_Hashtable<>::_InsertInfo): New struct.
            (_Hashtable<>::_M_get_insert_info): New, return latter.
            (_Hashtable<>::_M_insert_multi_node): Add _InsertInfo parameter.             (_Hashtable<>::_M_insert_unique_node): Add __node_ptr hint parameter.             (_Hashtable<>::_M_emplace_unique(__node_ptr, _Args&&...)): New.             (_Hashtable<>::_M_emplace_multi(__node_ptr, _Args&&...)): New.
            (_Hashtable<>::_M_emplace()): Adapt to use latters.
            (_Hashtable<>::_M_insert_unique): Add __node_ptr parameter.
            (_Hashtable<>::_M_insert_unique_aux): Add __node_ptr parameter.             (_Hashtable<>::_M_insert(__node_ptr, _Arg&&, const _NodeGenerator&, true_type)):
            Use latter.
            (_Hashtable<>::_M_reinsert_node(const_iterator, node_type&&)):
            Add hint parameter, adapt to use it.
            (_Hashtable<>::_M_reinsert_node_multi): Use hint parameter if available to extract
            hash code.
            (_Hashtable<>::_M_compute_hash_code(const _Hash&, __node_ptr, __node_ptr,
            const key_type&)): New.
(_Hashtable<>::_M_compute_hash_code<_H2>(const _H2&, __node_ptr, __node_ptr,
            const key_type&)): New.
            (_Hashtable<>::_M_merge_unique): Adapt to use latter. Implement small size
            optimization.
            (_Hashtable<>::_M_get_insert_info(const _Hash&, __node_ptr, __node_ptr,
            const key_type&)): New.
(_Hashtable<>::_M_get_insert_info<_H2>(const _H2&, __node_ptr, __node_ptr,
            const key_type&)): New.
            (_Hashtable<>::_M_merge_multi): Adapt to use latter.
            * include/bits/unordered_map.h (unordered_map<>::insert(node_type&&)): Pass cend as
            hint.
            (unordered_map<>::insert(const_iterator, node_type&&)): Adapt to use hint.             * include/bits/unordered_set.h (unordered_set<>::insert(node_type&&)): Pass cend as
            hint.
            (unordered_set<>::insert(const_iterator, node_type&&)): Adapt to use hint.             * testsuite/23_containers/unordered_multimap/insert/hint.cc: Adapt implementation
            specific tests.

Tested under linux x86_64.

Here is the performance results of this patch, before:

unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 insertions w/o hint      94r   94u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 insertions with perfect hint      95r   94u    0s 191999712mem 0pf unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 insertions with bad hint      94r   94u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 range insertions      88r   88u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 insertions w/o hint      91r   91u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 insertions with perfect hint      92r   93u    0s 191999712mem 0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 insertions with bad hint      93r   93u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 range insertions      88r   88u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 insertions w/o hint      94r   95u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 insertions with perfect hint      94r   95u    0s 191999712mem 0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 insertions with bad hint      94r   94u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 range insertions      90r   90u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code cached 2000000 insertions w/o hint      68r   68u    0s 223999264mem    0pf unordered_set_hint.cc-thread    hash code cached 2000000 insertions with perfect hint      67r   67u    0s 223999264mem 0pf unordered_set_hint.cc-thread    hash code cached 2000000 insertions with bad hint      68r   68u    0s 223999264mem    0pf unordered_set_hint.cc-thread    hash code cached 2000000 range insertions      62r   62u    0s 223999264mem    0pf

After:

unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 insertions w/o hint      93r   93u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 insertions with perfect hint      58r   59u    0s 191999712mem 0pf unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 insertions with bad hint      93r   94u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code NOT cached 2000000 range insertions      52r   51u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 insertions w/o hint      96r   95u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 insertions with perfect hint      61r   62u    0s 191999712mem 0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 insertions with bad hint      94r   94u    0s 191999712mem    0pf unordered_multiset_hint.cc-thread    hash code cached 2000000 range insertions      52r   52u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 insertions w/o hint      96r   95u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 insertions with perfect hint      58r   59u    0s 191999712mem 0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 insertions with bad hint      94r   94u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code NOT cached 2000000 range insertions      52r   52u    0s 191999712mem    0pf unordered_set_hint.cc-thread    hash code cached 2000000 insertions w/o hint      70r   69u    0s 223999264mem    0pf unordered_set_hint.cc-thread    hash code cached 2000000 insertions with perfect hint      67r   67u    0s 223999264mem 0pf unordered_set_hint.cc-thread    hash code cached 2000000 insertions with bad hint      67r   67u    0s 223999264mem    0pf unordered_set_hint.cc-thread    hash code cached 2000000 range insertions      63r   62u    0s 223999264mem    0pf

Ok to commit ?

François

Reply via email to