4 ms·
This goes to show that sometimes it really pays to read the docs: the doc comment of "fill" says "For char types filling contiguous areas of memory, this become
by rob74 7y ago
This goes to show that sometimes it really pays to read the docs: the doc comment of "fill" says "For char types filling contiguous areas of memory, this becomes an inline call to @c memset or @c wmemset"...
- IshKebab 7y agoYes that was mentioned in the article.
- gpderetta 7y agoarguably is still a standard library bug (or better, missed optimization). What triggers the optimization should be the value type of the range, not the type of the value to be filled in. The issue here is a quirk of overloading rules: after template instantiations two overloads of __fill_a are available, one with a deduced 'int' type for the fill value type and another with a 'char' type. Both are perfectly valid instantiations, but the 'int' valued one is preferred by the partial ordering rules as it does not require a conversion. I think this might easily be solved by making the type of the value to be filled in a separate template parameter even for the pointer variant. Also, in addition to pointers, the memset optimization should really be applied for all contiguous iterators (for example std::vector::iterator). Just use -O3. edit: minor fixes and rewording.
- quietbritishjim 7y ago> What triggers the optimization should be the value type of the range, not the type of the value to be filled in. As the article says, you have to do at least some checking on the type of the source value, because it could be a user-defined type with an overloaded implicit conversion operator (operator char()) that does something non-trivial. (I'm not completely sure that my comment contradicts what you've just said, but that's because I don't quite see what you're saying.)
- gpderetta 7y agoSure, but the enable_if<is_scalar<> > already takes care of it, I'm not suggesting taking the check away (although it might be possible to relax it to checking whether a type is trivially constructible and copyable). Now that I think of it you probably need to check that both the iterator value type and the value itself are trivially copyable, constructible and that the value is trivially convertible to the iterator value type itself. No wonder that the std library maintainers went for the easier way.
- BeeOnRope 7y ago> The issue here is a quirk of overloading rules: after template instantiations two overloads of __fill_a are available, one with a deduced 'int' type for the fill value type and another with a 'char' type. Both are perfectly valid instantiations, but the 'int' valued one is preferred by the partial ordering rules as it does not require a conversion. Eh right, that's something I somewhat misunderstood. I just thought the memset overload didn't match at all because the pointer and value-to-fill types are different, but of course it would match, with a conversion: but the other overload wins as you point out. > I think this might easily be solved by making the type of the value to be filled in a separate template parameter even for the pointer variant. Yeah, although you'd need a couple variants of that still with different enable_if conditions to filter the safe cases for this optimization ("complex" value-to-fill types can't use this, for some unclear definition of "complex"). > Also, in addition to pointers, the memset optimization should really be applied for all contiguous iterators (for example std::vector::iterator). This already works, see fill3 at [1]. I didn't check, but assumed decaying certain iterators to pointers was the function of the `std::__niter_base(iter)` calls in std::fill. --- [1] https://godbolt.org/z/Eqcsx7 https://godbolt.org/z/Eqcsx7
- BeeOnRope 7y agoThe "doc" here are comments on the std::fill function in gcc, not the actual reference doc for std::fill. It isn't even correct: 1) I find no evidence wmemset is ever used (e.g., for wchar_t). 2) It doesn't work for "char types", as in the example in this post: the memory is char type but when literal zero is passed, it breaks.
- aidenn0 7y agoOne of my favorite truisms about reading code is "comments are the only part of the code you can be sure aren't tested"