Common Lisp最適化入門
TOYOZUMIKouichi
FILMASSEMBLER
・具体例とかしくみより「こんなのがあるよ」
・実行時間は三回計測って中央値
 ・ろくなサンプルではないので、参考までに
・ポン付けできる最適化手法のみ
・マルチスレッドはなし
・OSX+SBCLで書いてます
1. 最適化のためのツール
2. 型...
最適化のためのツール1 TIME
マクロTIME formの実行時間やメモリ確保量を測る
(time form)
(defun twice (n)
(* n 2))
(time (loop for n from 0 to 10000000 co...
最適化のためのツール2 DISASSEMBLE
マクロDISASSEMBLE fnを逆アセンブルして出力する
(disassemble fn)
(defun twice (n)
(* n 2))
(disassemble #‘twice)
; ...
型付け1
FILMASSEMBLER
型を指定して型判定処理を外し、高速化する
(defun twice (n)
(declare (fixnum n))
(* n 2))
; disassembly for TWICE
; Size: 46 ...
型付け2
FILMASSEMBLER
LET式
(let ((a 20))
(declare (fixnum a)))
...
多値の束縛
(multiple-value-bind (a b c) ...
(declare (single-fl...
型付け3
FILMASSEMBLER
型付け前
Evaluation took:
0.224 seconds of real time
0.223692 seconds of total run time (0.181016 user, 0.0...
コンパイルオプション1
FILMASSEMBLER
おそらく最も強力なのは(safety 0)指定
(defun twice (n)
(declare (fixnum n)
(optimize (safety 0)))
(* n 2))
; d...
コンパイルオプション2
FILMASSEMBLER
基本的にこの設定にしておけば一番早い
(defun twice (n)
(declare (fixnum n)
(optimize (safety 0) (space 0) (debug 0)...
インライン展開1
FILMASSEMBLER
(defun twice (n)
(declare (fixnum n)
(optimize (safety 0) (space 0) (debug 0) (speed 3)))
(* n 2))
...
インライン展開2
FILMASSEMBLER
(declaim (inline twice))
(defun twice (n)
(declare (fixnum n)
(optimize (safety 0) (space 0) (debug...
インライン展開3
FILMASSEMBLER
インライン展開なし
Evaluation took:
0.225 seconds of real time
0.225405 seconds of total run time (0.175189 ...
L4S
FILMASSEMBLER
これを
(declaim (inline twice))
(defun twice (n)
(declare (fixnum n)
(optimize (safety 0) (space 0) (debug ...
CL-SIMD
FILMASSEMBLER
・https://github.com/angavrilov/cl-simd
・Common LispでSSEのイントリンシック命令を使う
・SBCLのコンパイル時に:sb-simd-packをena...
今日話したこと
FILMASSEMBLER
1. 最適化のためのツール
 TIME
 DISASSEMBLE
2. 型付け
3. 最適化オプション
 (SAFETY 0)がパワフル
4. インライン展開
5. L4S
 簡単な最適化に必要なオプ...
Upcoming SlideShare
Loading in …5
×

Common lisp最適化入門

4,873 views

Published on

Lisp Meet Up presented by Shibuya.lisp #15発表資料

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,873
On SlideShare
0
From Embeds
0
Number of Embeds
2,935
Actions
Shares
0
Downloads
13
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Common lisp最適化入門

  1. 1. Common Lisp最適化入門 TOYOZUMIKouichi FILMASSEMBLER
  2. 2. ・具体例とかしくみより「こんなのがあるよ」 ・実行時間は三回計測って中央値  ・ろくなサンプルではないので、参考までに ・ポン付けできる最適化手法のみ ・マルチスレッドはなし ・OSX+SBCLで書いてます 1. 最適化のためのツール 2. 型付け 3. 最適化オプション 4. インライン展開 5. L4S 6. CL-SIMD 今日話すこと FILMASSEMBLER
  3. 3. 最適化のためのツール1 TIME マクロTIME formの実行時間やメモリ確保量を測る (time form) (defun twice (n) (* n 2)) (time (loop for n from 0 to 10000000 collect (twice n))) Evaluation took: 0.224 seconds of real time 0.223692 seconds of total run time (0.181016 user, 0.042676 system) [ Run times consist of 0.149 seconds GC time, and 0.075 seconds non-GC time. ] 100.00% CPU 758,830,043 processor cycles 159,995,008 bytes consed ・あまりに複雑なことをすると壊れる ・壊れた場合はUNIXのtimeコマンドで計測 ・GCを走らせてから使わないと安定しない ・マルチスレッドで処理を走らせると特殊な結果が出る FILMASSEMBLER
  4. 4. 最適化のためのツール2 DISASSEMBLE マクロDISASSEMBLE fnを逆アセンブルして出力する (disassemble fn) (defun twice (n) (* n 2)) (disassemble #‘twice) ; disassembly for TWICE ; Size: 33 bytes ; 08D6ABEC: BF04000000 MOV EDI, 4 ; no-arg-parsing entry point ; BF1: 488BD3 MOV RDX, RBX ; BF4: 41BBD9020020 MOV R11D, 536871641 ; GENERIC-* ; BFA: 41FFD3 CALL R11 ; BFD: 488B5DF8 MOV RBX, [RBP-8] ; C01: 488BE5 MOV RSP, RBP ; C04: F8 CLC ; C05: 5D POP RBP ; C06: C3 RET ; C07: 0F0B0A BREAK 10 ; error trap ; C0A: 02 BYTE #X02 ; C0B: 19 BYTE #X19 ; INVALID-ARG-COUNT-ERROR ; C0C: 9A BYTE #X9A ; RCX FILMASSEMBLER
  5. 5. 型付け1 FILMASSEMBLER 型を指定して型判定処理を外し、高速化する (defun twice (n) (declare (fixnum n)) (* n 2)) ; disassembly for TWICE ; Size: 46 bytes ; 0915D31D: 488BD1 MOV RDX, RCX ; no-arg-parsing entry point ; 20: 48D1FA SAR RDX, 1 ; 23: 48D1E2 SHL RDX, 1 ; このへんのGENERICがない ; 26: 48D1E2 SHL RDX, 1 ; 29: 710C JNO L0 ; 2B: 48D1DA RCR RDX, 1 ; 2E: 41BB40060020 MOV R11D, 536872512 ; ALLOC-SIGNED-BIGNUM-IN- RDX ; 34: 41FFD3 CALL R11 ...... 右側を見てるとなんとなくわかるようになります。
  6. 6. 型付け2 FILMASSEMBLER LET式 (let ((a 20)) (declare (fixnum a))) ... 多値の束縛 (multiple-value-bind (a b c) ... (declare (single-float a b c)) ... LOOPマクロにおいて (loop for n fixnum from 0 below 10 do ...) 返り値の型指定 (+ 20 (the fixnum (twice 40))) 配列の宣言 (make-array '(10000000) :element-type 'single-float) ;; シングルクォートが必要なことに注意
  7. 7. 型付け3 FILMASSEMBLER 型付け前 Evaluation took: 0.224 seconds of real time 0.223692 seconds of total run time (0.181016 user, 0.042676 system) [ Run times consist of 0.149 seconds GC time, and 0.075 seconds non-GC time. ] 100.00% CPU 758,830,043 processor cycles 159,995,008 bytes consed 型付け後 Evaluation took: 0.211 seconds of real time 0.210294 seconds of total run time (0.168209 user, 0.042085 system) [ Run times consist of 0.148 seconds GC time, and 0.063 seconds non-GC time. ] 99.53% CPU 713,355,408 processor cycles 159,997,152 bytes consed
  8. 8. コンパイルオプション1 FILMASSEMBLER おそらく最も強力なのは(safety 0)指定 (defun twice (n) (declare (fixnum n) (optimize (safety 0))) (* n 2)) ; disassembly for TWICE ; Size: 27 bytes ; 06745875: 488D1409 LEA RDX, [RCX+RCX] ; no-arg-parsing entry point ; 79: 48D1E2 SHL RDX, 1 ; 7C: 710C JNO L0 ; 7E: 48D1DA RCR RDX, 1 ; 81: 41BB40060020 MOV R11D, 536872512 ; ALLOC-SIGNED-BIGNUM-IN- RDX ; 87: 41FFD3 CALL R11 ; 8A: L0: 488BE5 MOV RSP, RBP ; 8D: F8 CLC ; 8E: 5D POP RBP ; 8F: C3 RET 引数の数がおかしいとか、型がおかしいとか確認しない
  9. 9. コンパイルオプション2 FILMASSEMBLER 基本的にこの設定にしておけば一番早い (defun twice (n) (declare (fixnum n) (optimize (safety 0) (space 0) (debug 0) (speed 3))) (* n 2)) ・配列の添字境界検査とかも排除されます ・基本エラートラップがされなくなるので、つらいかも ・最適化への障害(型が不定)などはコンパイル時ノート が出ます ; note: unable to ; optimize ; due to type uncertainty: ; The first argument is a NUMBER, not a RATIONAL.
  10. 10. インライン展開1 FILMASSEMBLER (defun twice (n) (declare (fixnum n) (optimize (safety 0) (space 0) (debug 0) (speed 3))) (* n 2)) (defun test (n) (declare (fixnum n) (optimize (safety 0) (space 0) (debug 0) (speed 3))) (+ 10 n (the fixnum (twice 40)))) ; 06792875: 4883C60A ADD RSI, 10 ; no-arg-parsing entry point ; 79: 488975F8 MOV [RBP-8], RSI ; 7D: 488D5C24F0 LEA RBX, [RSP-16] ; 82: 4883EC18 SUB RSP, 24 ; 86: BA50000000 MOV EDX, 80 ; 8B: 488B0596FFFFFF MOV RAX, [RIP-106] ; #<FDEFINITION object for TWICE> ; 92: B902000000 MOV ECX, 2 ; 97: 48892B MOV [RBX], RBP ......
  11. 11. インライン展開2 FILMASSEMBLER (declaim (inline twice)) (defun twice (n) (declare (fixnum n) (optimize (safety 0) (space 0) (debug 0) (speed 3))) (* n 2)) (defun test (n) (declare (fixnum n) (optimize (safety 0) (space 0) (debug 0) (speed 3))) (+ 10 n (the fixnum (twice 40)))) ; 0693B9C5: 4883C15A ADD RCX, 90 ; no-arg-parsing entry point ; C9: 488BD1 MOV RDX, RCX ; TWICEの呼び出しが消滅 ; CC: 48D1E2 SHL RDX, 1 ; CF: 710C JNO L0 ; D1: 488BD1 MOV RDX, RCX ; D4: 41BB40060020 MOV R11D, 536872512 ; ALLOC-SIGNED-BIGNUM-IN- RDX ; DA: 41FFD3 CALL R11 ; DD: L0: 488BE5 MOV RSP, RBP ; E0: F8 CLC ; E1: 5D POP RBP ; E2: C3 RET
  12. 12. インライン展開3 FILMASSEMBLER インライン展開なし Evaluation took: 0.225 seconds of real time 0.225405 seconds of total run time (0.175189 user, 0.050216 system) [ Run times consist of 0.161 seconds GC time, and 0.065 seconds non-GC time. ] 100.00% CPU 764,645,525 processor cycles 159,997,648 bytes consed インライン展開あり Evaluation took: 0.207 seconds of real time 0.206800 seconds of total run time (0.159939 user, 0.046861 system) [ Run times consist of 0.158 seconds GC time, and 0.049 seconds non-GC time. ] 100.00% CPU 701,559,455 processor cycles 159,997,728 bytes consed
  13. 13. L4S FILMASSEMBLER これを (declaim (inline twice)) (defun twice (n) (declare (fixnum n) (optimize (safety 0) (space 0) (debug 0) (speed 3))) (* n 2)) こうできます (defunsafe fixnum twice ((fixnum n)) (* n 2)) 他にも (typed-let ((fixnum n) 20) ...) (typed-multiple-value-bind ((fixnum a b c)) ...) (typed-lambda ((single-float f) (list ls)) ...) とかできます。 https://github.com/TOYOZUMIKouichi/L4S
  14. 14. CL-SIMD FILMASSEMBLER ・https://github.com/angavrilov/cl-simd ・Common LispでSSEのイントリンシック命令を使う ・SBCLのコンパイル時に:sb-simd-packをenableに ・大変壊れやすく、注意が必要です ・https://github.com/TOYOZUMIKouichi/cl-simd  ・feature/sse3.1and4  ・SSE3.1と4の一部命令が使え(るはず)  ・結構簡単に増やせ(ていると思いこんでいる)
  15. 15. 今日話したこと FILMASSEMBLER 1. 最適化のためのツール  TIME  DISASSEMBLE 2. 型付け 3. 最適化オプション  (SAFETY 0)がパワフル 4. インライン展開 5. L4S  簡単な最適化に必要なオプションを短く記述 6. CL-SIMD  SSEのイントリンシック命令が使える  壊れやすい

×