[Bug libstdc++/54075] [4.7.1] unordered_map insert still slower than 4.6.2

François Dumont frs.dumont@gmail.com
Sun Nov 18 20:27:00 GMT 2012


On 11/16/2012 02:51 AM, Jonathan Wakely wrote:
> On 15 November 2012 21:00, François Dumont wrote:
>> On 11/14/2012 11:48 PM, Paolo Carlini wrote:
>>> Can somebody remind me why *exactly* we have a condition having to do with
>>> the empty-ness of the functor?
>>
>>      Because when hash code is not cache we need to embed the hash functor
>> into the local iterator implementation. So to minimize local implementation
>> memory footprint we prefered to cache the hash code as soon as it is not
>> empty.
> What if sizeof(functor) == 4, it will still be smaller than the size_t
> hash code, right? (At least for common 64-bit platforms.) And if
> sizeof(functor) == sizeof(size_t) it doesn't increase the footprint to
> store the functor.
I meant I wanted to minimize sizeof(local_iterator). iterators are most 
of the time passed by value to it is better to make them small, no ?
>    And if sizeof(functor) > sizeof(size_t) then could
> we store a single copy of the functor somewhere and store a pointer to
> it in each node? That would have the same size as the hash code, so we
> never increase the size of a node by more than sizeof(functor*), and
> the memory footprint is bounded. Is that possible?
>
> Do we have any performance numbers showing the impact of different
> sizes of functor stored in the nodes?
No cause the functor is not stored in hashtable nodes but in 
local_iterator when hash codes are not cached.
>
> But anyway, surely non-empty functors are not the common case, so are
> unlikely to be a performance problem for most users.
Agree
>
> Do we have any idea why caching the hash code seems to be slower than
> recalculating it?
Martin Cracauer in comment #31 is saying: "As you can see there also is 
a reasonably catastrophic increase in minor page
faults". I think it is the source of the peformance issue.
>
>
>>      Isn't gcc going to consider functor as noexcept even without the
>> noexcept qualifier ? Analyzing the code gcc could guess it, no ?
> No.
>
> You seem to be confusing what the optimisers can do and the
> language-level `noexcept' operator.  The optimisers can do clever
> analysis to change code generation, but the result of the noexcept
> operator does not depend on such clever analysis. Try
>
> void f() { }
> static_assert( noexcept(f()), "" );
>
> The assertion fails. Obviously this function cannot throw, but it is
> not "noexcept"
>
> Traits such as is_nothrow_constructible and move_if_noexcept and
> __is_noexcept_hash depend *only* on the statically provable "noexcept"
> property, *not* on how smart the optimisers are.
Ok, good to know.
>> Users might not being force to forget about optimization just to cache hash
>> code or not.
> I don't understand what you mean here, sorry.
>
> If not caching always(?) makes things faster then it seems sensible to
> only cache when we really need to (i.e. when the functor can throw)
     No, not caching do not always make things faster. 
performance/23_containers/insert_erase/41975.cc is testing behavior of 
unordered containers using a string key. It shows that with string it is 
better to cache hash code. So if adding noexcept might improve generated 
code but is also making behavior of unordered container worst users 
might complains of not being able to have best performance in both 
cases. But I guess impact of caching hash code is higher than the one of 
noexcept on code generation so it is surely not a big problem.

François



More information about the Libstdc++ mailing list