Many standard Common Lisp functions, particularly those which do simple calculations or access data from arrays or structures, can be compiled inline by the compiler. Inline compilation results in faster, often significantly faster run times as the function call and return overheads are saved.
But there are tricks to getting the compiler to inline, and there are tools which assist is expalining what the compiler is doing. In this note, we take a simple function with a call to the math function round, and try to get the call to round to inline. Here is the function:
(defun foo (x) (declare (optimize (speed 3) (safety 0) (debug 0)) (double-float x)) (round (* x x)))
round looks like a good candidate for inlining: the type of its argument is known and speed, safety, and debug have values calling for maximum speed. But when it is compiled and the compiled function is disassembled, we see that round was not inlined:
cl-user(10): (compile 'foo)
foo
nil
nil
cl-user(11): (disassemble 'foo)
;; disassembly of #<Function foo>
;; formals: x
;; constant vector:
0: round
;; code start: #x10003508c80:
0: 48 83 ec 68 sub rsp,$104
4: 4c 89 74 24 08 movq [rsp+8],r14
9: f2 44 0f 10 6f movsd xmm13,[rdi-10]
f6
15: f2 45 0f 59 ed mulsd xmm13,xmm13
20: f2 45 0f 10 fd movsd xmm15,xmm13
25: 31 c0 xorl eax,eax
27: 41 ff 97 d7 03 call *[r15+983] ; sys::new-double-float
00 00
34: 4c 89 7c 24 18 movq [rsp+24],r15
39: 48 8d 64 24 68 leaq rsp,[rsp+104]
44: 49 8b 6e 36 movq rbp,[r14+54] ; round
48: b0 08 movb al,$8
50: ff e3 jmp *rbx
cl-user(11):
The line labeled 44 is the jump to the round function.
So what went wrong?
No comments:
Post a Comment