• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Common lisp最適化入門
 

Common lisp最適化入門

on

  • 1,619 views

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

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

Statistics

Views

Total Views
1,619
Views on SlideShare
490
Embed Views
1,129

Actions

Likes
2
Downloads
1
Comments
0

5 Embeds 1,129

http://shibuya.lisp-users.org 985
https://twitter.com 112
http://127.0.0.1 24
http://www.slideee.com 5
http://www.google.co.jp 3

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Common lisp最適化入門 Common lisp最適化入門 Presentation Transcript

    • Common Lisp最適化入門 TOYOZUMIKouichi FILMASSEMBLER
    • ・具体例とかしくみより「こんなのがあるよ」 ・実行時間は三回計測って中央値  ・ろくなサンプルではないので、参考までに ・ポン付けできる最適化手法のみ ・マルチスレッドはなし ・OSX+SBCLで書いてます 1. 最適化のためのツール 2. 型付け 3. 最適化オプション 4. インライン展開 5. L4S 6. CL-SIMD 今日話すこと FILMASSEMBLER
    • 最適化のためのツール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
    • 最適化のためのツール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
    • 型付け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 ...... 右側を見てるとなんとなくわかるようになります。
    • 型付け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) ;; シングルクォートが必要なことに注意
    • 型付け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
    • コンパイルオプション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 引数の数がおかしいとか、型がおかしいとか確認しない
    • コンパイルオプション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.
    • インライン展開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 ......
    • インライン展開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
    • インライン展開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
    • 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
    • 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の一部命令が使え(るはず)  ・結構簡単に増やせ(ていると思いこんでいる)
    • 今日話したこと FILMASSEMBLER 1. 最適化のためのツール  TIME  DISASSEMBLE 2. 型付け 3. 最適化オプション  (SAFETY 0)がパワフル 4. インライン展開 5. L4S  簡単な最適化に必要なオプションを短く記述 6. CL-SIMD  SSEのイントリンシック命令が使える  壊れやすい