(どうでも良い)SBCLクイズ: 空ループの最適化 — #:g1

Posted 2011-05-07 08:04:00 GMT

(defun foo-slow ()
  (let* ((numbers (coerce (- 0 1) 'number)))
    (declare (type number numbers))
    (tagbody
      LL
      (setq numbers (+ numbers (coerce 1 'number)))
      (if (> numbers (* 10000 10000))
          (go END))
      (go LL)
      END)
    nil))
というコードがあります。
これは、Series
(collect-ignore (scan-range :from 0 :upto (* 10000 10000)))
のマクロの展開結果で、単に空のループを1億回実行するというものですが、実行スピードが LOOP マクロの同等のコードより10倍位遅いのが悔しいので、同じ位高速なfoo-fastを作成してください、というのが問題です。

実行速度

(foo-slow)
;⇒ NIL
----------
Evaluation took:
  0.520 seconds of real time
  0.520000 seconds of total run time (0.520000 user, 0.000000 system)
  100.00% CPU
  1,242,649,269 processor cycles
  0 bytes consed

Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz

(defun bar-fast ()
  (loop :repeat (* 10000 10000)))

(bar-fast) ;⇒ NIL ---------- Evaluation took: 0.045 seconds of real time 0.040000 seconds of total run time (0.040000 user, 0.000000 system) 88.89% CPU 106,853,454 processor cycles 0 bytes consed

Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz

foo-slowのDISASSEMBLEの結果は、
; disassembly for FOO-SLOW
; 18029EF4:       48C7C3F8FFFFFF   MOV RBX, -8                ; no-arg-parsing entry point
;      EFB:       90               NOP
;      EFC:       90               NOP
;      EFD:       90               NOP
;      EFE:       90               NOP
;      EFF:       90               NOP
;      F00: L0:   BF08000000       MOV EDI, 8
;      F05:       488BD3           MOV RDX, RBX
;      F08:       4C8D1C25E0010020 LEA R11, [#x200001E0]      ; GENERIC-+
;      F10:       41FFD3           CALL R11
;      F13:       480F42E3         CMOVB RSP, RBX
;      F17:       488BDA           MOV RBX, RDX
;      F1A:       48895DF8         MOV [RBP-8], RBX
;      F1E:       BF0008AF2F       MOV EDI, 800000000
;      F23:       488BD3           MOV RDX, RBX
;      F26:       488D0C2544040020 LEA RCX, [#x20000444]      ; GENERIC->
;      F2E:       FFD1             CALL RCX
;      F30:       488B5DF8         MOV RBX, [RBP-8]
;      F34:       7ECA             JLE L0
;      F36:       BA17001020       MOV EDX, 537919511
;      F3B:       488BE5           MOV RSP, RBP
;      F3E:       F8               CLC
;      F3F:       5D               POP RBP
;      F40:       C3               RET
;      F41:       CC0A             BREAK 10                   ; error trap
;      F43:       02               BYTE #X02
;      F44:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;      F45:       54               BYTE #X54                  ; RCX
ですが、bar-fastのDISASSEMBLE結果は、
; disassembly for BAR-FAST
; 19357284:       B90008AF2F       MOV ECX, 800000000         ; no-arg-parsing entry point
;       89:       EB09             JMP L1
;       8B:       90               NOP
;       8C:       90               NOP
;       8D:       90               NOP
;       8E:       90               NOP
;       8F:       90               NOP
;       90: L0:   4883E908         SUB RCX, 8
;       94: L1:   4883F900         CMP RCX, 0
;       98:       7FF6             JNLE L0
;       9A:       BA17001020       MOV EDX, 537919511
;       9F:       488BE5           MOV RSP, RBP
;       A2:       F8               CLC
;       A3:       5D               POP RBP
;       A4:       C3               RET
;       A5:       CC0A             BREAK 10                   ; error trap
;       A7:       02               BYTE #X02
;       A8:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;       A9:       54               BYTE #X54                  ; RCX
;       AA:       CC0A             BREAK 10                   ; error trap
;       AC:       02               BYTE #X02
;       AD:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;       AE:       54               BYTE #X54                  ; RCX
です。foo-fastは
; disassembly for FOO-FAST
; 18229894:       31C9             XOR ECX, ECX               ; no-arg-parsing entry point
;       96:       EB0C             JMP L1
;       98:       90               NOP
;       99:       90               NOP
;       9A:       90               NOP
;       9B:       90               NOP
;       9C:       90               NOP
;       9D:       90               NOP
;       9E:       90               NOP
;       9F:       90               NOP
;       A0: L0:   4883C108         ADD RCX, 8
;       A4: L1:   4881F90008AF2F   CMP RCX, 800000000
;       AB:       7EF3             JLE L0
;       AD:       BA17001020       MOV EDX, 537919511
;       B2:       488BE5           MOV RSP, RBP
;       B5:       F8               CLC
;       B6:       5D               POP RBP
;       B7:       C3               RET
;       B8:       CC0A             BREAK 10                   ; error trap
;       BA:       02               BYTE #X02
;       BB:       18               BYTE #X18                  ; INVALID-ARG-COUNT-ERROR
;       BC:       54               BYTE #X54                  ; RCX
のようなものになると思われます。

comments powered by Disqus