There is no mention of the fact that the STL implementation is very generic, it only assumes operator++ and operator* on the iteration, and operator The "optimized" versions here all make more assumptions on the iterator, starting from operator+(int) in Version 1, so it no longer works on iterators with just "forward_iterator_tag". Further versions even restrict vector sizes (albeit to a very high number) and assign…
How We Beat C++ STL Binary Search
31–40 of 52 posts
Re: How We Beat C++ STL Binary Search
#32There is no mention of the fact that the STL implementation is very generic, it only assumes operator++ and operator* on the iteration, and operator The "optimized" versions here all make more assumptions on the iterator, starting from operator+(int) in Version 1, so it no longer works on iterators with just "forward_iterator_tag". Further versions even restrict vector sizes (albeit to a very high number) and assign…
Just a nitpick: Assigning a negative value to an unsigned integer is perfectly safe and well defined (i.e. integer overflow for unsigned integers is well defined in the C++ spec). Using -1 for size_t is sometimes even prefered to assign it's maximum value, since there is no cross-platform #define for it (most use either SIZE_T_MAX or SIZE_MAX). In fact llvm's libc++ uses it for it's std::numeric_limits implementation…
Re: How We Beat C++ STL Binary Search
#33Earlier quoted context omitted.
That blog is wrong. The program won't be undefined( unsigned wrap is defined ), but the offset will not be correct.
They didn't say unsigned overflow was undefined, but you're right that the offset won't be correct. I thought it seemed intuitively wrong to me, but I figured google research is probably a reliable source!
Re: How We Beat C++ STL Binary Search
#34Earlier quoted context omitted.
Well a branch will fetch the incorrect cache line if it mispredicts, but a conditional move will fetch both cache lines every time.
The conditional move is the statement `low = v >= value ? low : other_low;` which either assigns `other_low` to `low` or does nothing. And other_low is a variable, and not an arbitrary element of the list (which is a big difference with respect to cache), and it can also be seen from the assembly that it's stored in register. So there there is no "both cache lines" to fetch anything from.
Re: How We Beat C++ STL Binary Search
#35Re: How We Beat C++ STL Binary Search
#36Earlier quoted context omitted.
Not if low and high are both unsigned (size_t is unsigned.) Even if it overflows, the result will be correct. See: http://googleresearch.blogspot.com/2006/06/extra-extra-read-...
That blog is wrong. The program won't be undefined( unsigned wrap is defined ), but the offset will not be correct.
Re: How We Beat C++ STL Binary Search
#37There is no mention of the fact that the STL implementation is very generic, it only assumes operator++ and operator* on the iteration, and operator The "optimized" versions here all make more assumptions on the iterator, starting from operator+(int) in Version 1, so it no longer works on iterators with just "forward_iterator_tag". Further versions even restrict vector sizes (albeit to a very high number) and assign…
Is there any technical reason why the STL implementation can't include optimized specializations when there are less generic operators it can use?
Re: How We Beat C++ STL Binary Search
#38There is no mention of the fact that the STL implementation is very generic, it only assumes operator++ and operator* on the iteration, and operator The "optimized" versions here all make more assumptions on the iterator, starting from operator+(int) in Version 1, so it no longer works on iterators with just "forward_iterator_tag". Further versions even restrict vector sizes (albeit to a very high number) and assign…
Is there any technical reason why the STL implementation can't include optimized specializations when there are less generic operators it can use?
Re: How We Beat C++ STL Binary Search
#39Isn't version 2 wrong, because size_t probe = (low + high) / 2; may overflow?
True, but only if the list has more than 2^31 entries on a 32-bit machine. In practise that's not possible if it contains 32-bit integers because that would take up a 16 GB linear address space which doesn't exist on a 32-bit machine. An academically correct version would be `size_t probe = low + ((high - low) / 2);` but that would be much slower. You could instead just add an initial debug-mode-only assert on the li…