Boost C++ Libraries: Ticket #9233: Suboptimal shift by multiples of 8 bits https://svn.boost.org/trac10/ticket/9233 <p> It seems to me that the operation from the subject is needlessly fat, as if it is using a generic implementation for a generic/'random' number of bits... </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9233 Trac 1.4.3 John Maddock Sat, 12 Oct 2013 09:57:22 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9233#comment:1 https://svn.boost.org/trac10/ticket/9233#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> I don't believe there's any way to improve this - shifts by whole numbers of "limbs" are optimized, but individual bytes are not in a suitable order for a std::memmove for example. </p> Ticket Domagoj Šarić Thu, 18 Feb 2016 11:36:34 GMT <link>https://svn.boost.org/trac10/ticket/9233#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9233#comment:2</guid> <description> <p> Maybe you could add/separate specialized functions for shifting: for whole limbs, for whole bytes and 'generic'. Then the shift operator can be implemented as if ( bits % limb_bits == 0 ) shift_limbs(); elseif ( bits % 8 == 0 ) shift_bytes(); else { generic() }; and rely on IPO to directly select the optimal implementation when bits is a compile time constant... </p> <p> ps. why are limbs on win64 32bit integers (as opposed to 64 bit ones)? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>John Maddock</dc:creator> <pubDate>Wed, 24 Feb 2016 19:02:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9233#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9233#comment:3</guid> <description> <p> Fixed in <a class="ext-link" href="https://github.com/boostorg/multiprecision/commit/cb1a41835f4566987b96c7a7034088e22d83f77b"><span class="icon">​</span>https://github.com/boostorg/multiprecision/commit/cb1a41835f4566987b96c7a7034088e22d83f77b</a> </p> <p> It turns out that memmove is (very slightly) faster than moving whole limbs so that's the preferred method when available. </p> <p> Limbs are half the size of the largest available integers - so 32-bit for msvc as there's no 128-bit integer support (unlike mingw for example). </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Domagoj Šarić</dc:creator> <pubDate>Fri, 26 Feb 2016 10:19:04 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9233#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9233#comment:4</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/9233#comment:3" title="Comment 3">johnmaddock</a>: </p> <blockquote class="citation"> <p> Fixed in <a class="ext-link" href="https://github.com/boostorg/multiprecision/commit/cb1a41835f4566987b96c7a7034088e22d83f77b"><span class="icon">​</span>https://github.com/boostorg/multiprecision/commit/cb1a41835f4566987b96c7a7034088e22d83f77b</a> </p> </blockquote> <p> Thanks John :) I no longer use/need this functionality so I didn't test but from a cursory skim it looks good...except that maybe the (little) endian checks are not really necessary: if you make them in only one place - where you decide on the underlying/raw/limb layout - if you order the limbs in 'machine endianess' (I'm guessing) the rest of the code can be endianness agnostic (and more readily assume correct byte ordering/use memcpy/move/set more easily)... </p> <blockquote class="citation"> <p> It turns out that memmove is (very slightly) faster than moving whole limbs so that's the preferred method when available. </p> </blockquote> <p> It's also smaller (one call instead of a loop for every instantiation;) </p> <blockquote class="citation"> <p> Limbs are half the size of the largest available integers - so 32-bit for msvc as there's no 128-bit integer support (unlike mingw for example). </p> </blockquote> <p> Thanks for the explanation ;) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Fri, 26 Feb 2016 11:40:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9233#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9233#comment:5</guid> <description> <blockquote class="citation"> <p> if you order the limbs in 'machine endianess' (I'm guessing) the rest of the code can be endianness agnostic (and more readily assume correct byte ordering/use memcpy/move/set more easily) </p> </blockquote> <p> No I'd have to rewrite everything - multiplication, addition, subtraction, the works. Two versions for each, one little endian, one big. And I'd have no means of testing the big endian code either... </p> <p> Not going to happen, sorry! </p> </description> <category>Ticket</category> </item> </channel> </rss>