Last active
February 22, 2016 02:30
-
-
Save jackrusher/57525bef17382c9a7207 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; This is the sort of thing that makes me think you'd enjoy using one | |
;; of the better Common Lisp implementations for certain kinds of | |
;; work. I'm using the latest version of SBCL here. | |
;; Ok, contrived example, but easy to imagine the code that it should | |
;; generate... | |
(defun add (x y) | |
(+ x y)) | |
(disassemble #'add) | |
; disassembly for ADD | |
; Size: 41 bytes. Origin: #x1004CB7393 | |
; 93: 498B4C2460 MOV RCX, [R12+96] ; thread.binding-stack-pointer | |
; no-arg-parsing entry point | |
; 98: 48894DF8 MOV [RBP-8], RCX | |
; 9C: 488BD6 MOV RDX, RSI | |
; 9F: 488BFB MOV RDI, RBX | |
; A2: 41BBD0010020 MOV R11D, 536871376 ; GENERIC-+ | |
; A8: 41FFD3 CALL R11 | |
; AB: 488B5DE8 MOV RBX, [RBP-24] | |
; AF: 488B75F0 MOV RSI, [RBP-16] | |
; B3: 488BE5 MOV RSP, RBP | |
; B6: F8 CLC | |
; B7: 5D POP RBP | |
; B8: C3 RET | |
; B9: 0F0B10 BREAK 16 ; Invalid argument count trap | |
;; ... not terrible, especially for a runtime that provides arbitrary | |
;; precision arithmetic and traps errors in a civilized way, but with | |
;; safety and generic #'+ that figures out arity and handles different | |
;; types we pay a price in performance relative to the asm we'd write. | |
;; There are a number of different ways to speed this up: declaring a | |
;; greater speed to safety preference, annotating types. Here's an | |
;; optimized version with that sort of ugly cruft added to get really | |
;; good performance specifically for 32-bit integers. | |
(defun add (x y) | |
(declare | |
(type (unsigned-byte 32) x y) | |
(optimize (speed 3) (safety 0))) | |
(the (unsigned-byte 32) (+ x y))) | |
(disassemble #'add) | |
; disassembly for ADD | |
; Size: 12 bytes. Origin: #x1004CEFD82 | |
; 2: 4801F9 ADD RCX, RDI ; no-arg-parsing entry point | |
; 5: 488BD1 MOV RDX, RCX | |
; 8: 488BE5 MOV RSP, RBP | |
; B: F8 CLC | |
; C: 5D POP RBP | |
; D: C3 RET | |
;; ... I can definitely live with that. | |
;; We can write macros that produce code with these annotation to | |
;; compile our own high-level DSLs into the assembly we would have | |
;; written. Common Lisp has its warts, but it really is amazing when | |
;; it comes building whatever abstractions you prefer while retaining | |
;; control over low-level code generation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; I'm not sure what Common Lisp you're using, ot why you'd want to | |
;; use a counter to repeatedly poke some data into a value cell, but | |
;; but with SBCL's compiler I get: | |
(defun test () | |
(let ((x 0)) | |
(declare | |
(optimize (speed 3) (safety 0))) | |
(type (unsigned-byte 32) x) | |
(loop for i to 999999999 do (incf x)))) | |
(disassemble #'test) | |
; disassembly for TEST | |
; Size: 58 bytes. Origin: #x1004AA1614 | |
; 14: 498B442460 MOV RAX, [R12+96] ; thread.binding-stack-pointer | |
; no-arg-parsing entry point | |
; 19: 488945F8 MOV [RBP-8], RAX | |
; 1D: 31D2 XOR EDX, EDX | |
; 1F: 31C0 XOR EAX, EAX | |
; 21: EB15 JMP L1 | |
; 23: 660F1F840000000000 NOP | |
; 2C: 0F1F4000 NOP | |
; 30: L0: 4883C202 ADD RDX, 2 | |
; 34: 4883C002 ADD RAX, 2 | |
; 38: L1: 483DFE933577 CMP RAX, 1999999998 | |
; 3E: 7EF0 JLE L0 | |
; 40: BA17001020 MOV EDX, 537919511 | |
; 45: 488BE5 MOV RSP, RBP | |
; 48: F8 CLC | |
; 49: 5D POP RBP | |
; 4A: C3 RET | |
; 4B: 0F0B10 BREAK 16 ; Invalid argument count trap | |
;; ... which runs in 0.000586 seconds of system time at 99.67% CPU utilization: | |
;; 811,693,353 processor cycles | |
;; 0 bytes consed | |
;; ... note that this last bit means no memory was allocated during the function call and loop. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@jackrusher it doesn't work for me in neither lisp implementation:
Clisp
CBSL