3 ms·
Sort of. I think CL has the right direction but the details are wrong. This pattern requires declaring the function notinline, and that is a much stronger state
by thelopa 6y ago
Sort of. I think CL has the right direction but the details are wrong. This pattern requires declaring the function notinline, and that is a much stronger statement than just “wait I take it back”. Using this pattern, the function can ONLY be inlined in the contexts where you allow it. Similarly, compiler macros are disabled for notinline functions. I would like the compiler to use its normal judgement for inlining and continue using compiler macros for call sites where I don’t provide an inline declaration.
- patrec 6y agoI think you overlook that inlining in common lisp is a lot less trivial than in very static languages like C++, because it is perfectly valid to redefine functions at runtime. This does obviously not play well with the compiler randomly inlining things behind your back. You can fix that by keeping track of where you inlined f and then re-compile all the inlined sites as well, but that obviously has significant pathologies as well. Having said that, performance oriented common lisp compilers like sbcl (and its predecessor) will generally allow you to block-compile stuff which will get rid of the extra indirections at the cost of less runtime flexibility. IIRC that will also mean the compiler will use its judgement whether to inline a function.
- kazinator 6y agoCommon Lisp has pretty clear, straightforward rules about inlining. File compilation is allowed to automatically inline function calls that are in the same compilation unit as their target. This follows from the reasoning that material which is compiled together will be loaded together, and those functions will be redefined together. The details are in 3.2.2.3 Semantic Constraints, bullets 3-5. In any case where this inlining would be a problem, you must use declaim globally or declare locally to request notinline. Likewise, you can use an inline declaration to encourage inlining.
- patrec 6y agoYes, the standard allows this, but that doesn't mean inlining is straightforward, in the sense that the compiler can't just magically figure out unaided whether to inline stuff or not and all is well as the GP wanted. Whether two functions were defined in the same file has basically zero bearing on the desirability of inlining, so the fact that recompiling a whole file rather than an individual function is not particuarly onerous doesn't really help that much. Also, correct me if I'm wrong, but I don't think anything that sbcl does if you pass :block-compile t goes beyond what would already be allowed by the standard as default (by contrast, CMUCL's block compilation supported multiple files and thus essentially also whole-program optimization). The fact that it's not the default (despite likely non-trivial performance benefits) probably indicates that a majority of users would find this behavior problematic as default, regardless of whether it is standard conformant.
- lispm 6y ago> that the compiler can't just magically figure out unaided whether to inline stuff or not Allegro CL does inlining on its own, IIRC. > majority of users would find this behavior problematic as default Block compilation or whole program compilation are used for delivery of applications.
- patrec 6y ago> Block compilation or whole program compilation are used for delivery of applications. Mostly, sure just like LTO in C/C++. But if I were doing any scientific programming with common lisp I'd try to use block compilation in a few select places during interactive development as well. I'd imagine that for some code this would get rid of a lot of boxing and unboxing as well as type checks, in addition to getting rid of indirection. I'd not be surprised if you could get an integer factor speed up if you got many small functions which mostly operate on doubles or double arrays. I should probably give it a try just to satisfy my curiosity.