Boost C++ Libraries: Ticket #5735: proto should force functions to be inline https://svn.boost.org/trac10/ticket/5735 <p> Some functions in Boost.Proto should really always be inlined; unfortunately, they don't always properly get inlined, sometimes due to compiler bugs (I can think of problems with a certain GCC version on 64-bit for example). </p> <p> I suggest that Proto does what it can to force those functions to be inline (using <span class="underline">attribute</span>((always_inline)) on GCC and <span class="underline">forceinline with MSVC). This will also have the effect of yielding warnings when a function can't be inlined, and at least with GCC, functions will be inlined even in debug mode. </span></p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5735 Trac 1.4.3 Eric Niebler Tue, 26 Jul 2011 19:59:38 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/5735#comment:1 https://svn.boost.org/trac10/ticket/5735#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">invalid</span> </li> </ul> <p> This is none of Proto's business. If there is a compiler bug leading it to poorly inline, then it sould be fixed in the compiler, not worked around in Proto. Forcing inlining might actually degrade performance for compilers that have good inlining heuristics. </p> Ticket Mathias Gaunard Tue, 26 Jul 2011 21:24:06 GMT <link>https://svn.boost.org/trac10/ticket/5735#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5735#comment:2</guid> <description> <p> Since Proto is used to build many performance sensitive libraries and applications, and there is no downside to implementing this feature, I don't understand why you're discarding this request so easily. </p> <p> Proto is a library for others to build upon, each having their own uses, requirements, compilers and toolchains. No compiler is perfect, and inlining is certainly not a perfect feature and is very dependent of the flags used -- which themselves may have other negative effects. That means that you cannot rely on the compiler to do it reliably, especially when large codebases are involved. There are always inlining issues, different ones with each version of GCC for example, including recent and widely deployed ones. </p> <p> Some Proto constructs make no sense to not be inlined, so it seems like a good idea to tell the compiler that yes, they should always be inlined, and if it cannot for some reason, it should emit an error. It is also important in order to get decent performance when running the code in debug mode or in modes that are not too aggressive with inlining, such as size-optimized builds, popular on embedded systems. </p> <p> I believe doing this would only improve the quality of Proto and make people more eager to rely on it. </p> <p> I think the following paper, in section 9, sums up the importance of inlining with expression templates pretty well: <a class="ext-link" href="http://arxiv.org/pdf/1104.1729"><span class="icon">​</span>http://arxiv.org/pdf/1104.1729</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Tue, 26 Jul 2011 21:57:34 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5735#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5735#comment:3</guid> <description> <p> Wow, the paper is from this year, and they think that Blitz++ and uBLAS represent the bleeding edge of ET technology. That's laughable. </p> <p> But the perf measurements are interesting. I can't see where they say what compiler they're using for their perf benchmarks, can you? If they're using that buggy GCC compler version, then yes, it will grossly screw up the results. They talk about cache issues, but only consider data size and not code size. </p> <p> Joel Falcou is the one closest to this issue. He's filed specific bugs against Proto (function X should be changed in way Y for better inlining), which I have addressed promptly. He hasn't noticed any problems that would require any across-the-board change like the one you're suggesting. Or if he has, he hasn't said anything about it. If you can show me a specific case where a (non-buggy, mainstream) compiler generates slow Proto code because of failed inlining, I'd be more easily convinced. </p> <p> But you should bring this up on the Proto list and make sure Joel sees it. I'd be curious to hear his thoughts. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Mathias Gaunard</dc:creator> <pubDate>Tue, 26 Jul 2011 23:05:52 GMT</pubDate> <title>type changed https://svn.boost.org/trac10/ticket/5735#comment:4 https://svn.boost.org/trac10/ticket/5735#comment:4 <ul> <li><strong>type</strong> <span class="trac-field-old">Bugs</span> → <span class="trac-field-new">Feature Requests</span> </li> </ul> <p> Yes, that paper is "not terribly good", yet it has a couple of wise things in it, and the conclusion is interesting, which is why I put it there. (it's from Thomas Heller's advisor, by the way)<br /> I unfortunately don't have more information on how they got those results. </p> <p> I haven't personally run into problems with inlining and Boost.Proto, since I haven't done things that were very performance critical with it yet that required me to look at the produced asm, but I have run into issues in NT2 (in the non-ET parts) where some very small and trivial functions didn't get inlined on some GCC versions or settings, which was catastrophic to performance (hundreds of times slower).<br /> Some other NT2 users ran into similar problems on MSVC, albeit on different functions. </p> <p> I believe putting force inline attributes to functions is an even more reliable solution than making code "compiler-friendly", since this way we can have a guarantee that things will be inlined rather than analyzing asm and finding out a workaround on a case by case basis. </p> <p> I'm only suggesting that a BOOST_PROTO_FORCE_INLINE be put instead of inline in the cases where it appears to be a good idea. Is that considered to be too intrusive in the source code? </p> <p> In any case I'll get Joel in the loop. </p> Ticket anonymous Wed, 27 Jul 2011 07:55:57 GMT <link>https://svn.boost.org/trac10/ticket/5735#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5735#comment:5</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5735#comment:3" title="Comment 3">eric_niebler</a>: </p> <blockquote class="citation"> <p> Wow, the paper is from this year, and they think that Blitz++ and uBLAS represent the bleeding edge of ET technology. That's laughable. </p> </blockquote> <p> Yeah quite sad ... </p> <p> As for the problem at hand, I have mgaunard handy in my office, and as he said, we got some sporadic MSVC 10 with some size aggressive optimization. Now, I dont think we need an all-over-your-face approach but just have a force inline macro handy that me/you can apply where and when necessary. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Mathias Gaunard</dc:creator> <pubDate>Tue, 01 Nov 2011 13:39:50 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5735#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5735#comment:6</guid> <description> <p> I suggest at least proto::value(), proto::child, make_expr and related transforms be marked force inline. Looking at assembly, it happens relatively often that boost::proto::value is not inlined, even though it definitely should always be. </p> <p> boost/config.hpp now contains a BOOST_FORCEINLINE macro that can be used for this purpose. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Mathias Gaunard</dc:creator> <pubDate>Wed, 02 Nov 2011 11:06:04 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/5735 https://svn.boost.org/trac10/ticket/5735 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">proto_forceinline.tar.gz</span> </li> </ul> <p> Adds BOOST_FORCEINLINE in relevant parts of Boost.Proto </p> Ticket Mathias Gaunard Wed, 02 Nov 2011 11:15:19 GMT <link>https://svn.boost.org/trac10/ticket/5735#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5735#comment:7</guid> <description> <p> The attached patch adds BOOST_FORCEINLINE to the following functions: </p> <ul><li>as_lvalue, ignore_unused, dont_care </li><li>as_child, as_expr </li><li>proto_base, address_of_hack </li><li>child, child_c, value </li><li>make_expr, unpack_expr </li><li>operators and operators defined by extends, extends constructor </li><li>built-in generators </li><li>the transform operator() overloads that give dummy state and data </li><li>call, make, when and pass_through transforms </li></ul><p> This patch adds a significant number of BOOST_FORCEINLINE, but all of them make sense, because the functions in question are lightweight wrappers or only forward non-recursively to another function. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Sun, 20 Nov 2011 21:48:39 GMT</pubDate> <title>status, version changed; resolution deleted https://svn.boost.org/trac10/ticket/5735#comment:8 https://svn.boost.org/trac10/ticket/5735#comment:8 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.47.0</span> → <span class="trac-field-new">Boost 1.49.0</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> <p> This is fixed on trunk in <a class="changeset" href="https://svn.boost.org/trac10/changeset/75578" title="apply BOOST_FORCEINLINE patch">[75578]</a>. I'll merge this to release after the tests have cycles. Thanks, Mathias. </p> Ticket Eric Niebler Sat, 17 Dec 2011 19:17:46 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/5735#comment:9 https://svn.boost.org/trac10/ticket/5735#comment:9 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/76026" title="merge [75578] from trunk, fixes #5735">[76026]</a>) merge <a class="changeset" href="https://svn.boost.org/trac10/changeset/75578" title="apply BOOST_FORCEINLINE patch">[75578]</a> from trunk, fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5735" title="#5735: Feature Requests: proto should force functions to be inline (closed: fixed)">#5735</a> </p> Ticket