Opened 9 years ago

Last modified 7 years ago

#638 new defect

LOGBITP onerous penalty for fixnum type declaration around literal fixnum

Reported by: mhd Owned by: gb
Priority: normal Milestone:
Component: Compiler Version: 1.4
Keywords: Cc:

Description (last modified by gb)

Compilation of certain calls to LOGBITP results in an extremely onerous penalty for a fixnum type declaration wrapped around a constant fixnum index when using slow, safe compiler optimizations.

Note: the following report refers to lisp source code at end, (my file: ccl-bug-report.lisp).

The functions MYLOGBITP2 and MYLOGBITP4 are much slower. These are the two and only functions that call logbitp with first arg (the fixnum 0). See output of test function RUN-ALL below.

I have observed this is fixed with these fast compiler settings: (proclaim '(optimize (speed 3) (safety 0) (space 0)))



(proclaim '(optimize (speed 0) (safety 3) (space 0)))

(defun mylogbitp1 (integer)
  (logbitp 0 integer))

(defun mylogbitp2 (integer)
  (logbitp (the fixnum 0) (the fixnum integer)))

(defun mylogbitp3 (integer)
  (logbitp 0 (the fixnum integer)))

(defun mylogbitp4 (integer)
  (logbitp (the fixnum 0) integer))

(defun mylogbitp5 (index integer)
  (logbitp index integer))

(defun mylogbitp6 (index integer)
  (logbitp (the fixnum index) integer))

(defun mylogbitp7 (index integer)
  (logbitp index (the fixnum integer)))

(defun mylogbitp8 (index integer)
  (logbitp (the fixnum index) (the fixnum integer)))

(defun run (which n)
  (loop for i from 1 to n
        count (ecase which
                (1 (mylogbitp1 i))
                (2 (mylogbitp2 i))
                (3 (mylogbitp3 i))
                (4 (mylogbitp4 i))
                (5 (mylogbitp5 0 i))
                (6 (mylogbitp6 0 i))
                (7 (mylogbitp7 0 i))
                (8 (mylogbitp8 0 i)))))

(defun run-all ()
  (let ((n 10000000))
    (loop for which from 1 to 8
          do
          (print `(run ,which ,n))
          (time (funcall #'run which n)))))


----

Results of evaluating (RUN-ALL):

(RUN 1 10000000) 
(FUNCALL #'RUN WHICH N) took 594 milliseconds (0.594 seconds) to run 
                    with 2 available CPU cores.
During that period, 516 milliseconds (0.516 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.

(RUN 2 10000000) 
(FUNCALL #'RUN WHICH N) took 13,593 milliseconds (13.593 seconds) to run 
                    with 2 available CPU cores.
During that period, 12,687 milliseconds (12.687 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.

(RUN 3 10000000) 
(FUNCALL #'RUN WHICH N) took 782 milliseconds (0.782 seconds) to run 
                    with 2 available CPU cores.
During that period, 735 milliseconds (0.735 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.

(RUN 4 10000000) 
(FUNCALL #'RUN WHICH N) took 13,781 milliseconds (13.781 seconds) to run 
                    with 2 available CPU cores.
During that period, 13,093 milliseconds (13.093 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.

(RUN 5 10000000) 
(FUNCALL #'RUN WHICH N) took 859 milliseconds (0.859 seconds) to run 
                    with 2 available CPU cores.
During that period, 797 milliseconds (0.797 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.

(RUN 6 10000000) 
(FUNCALL #'RUN WHICH N) took 953 milliseconds (0.953 seconds) to run 
                    with 2 available CPU cores.
During that period, 766 milliseconds (0.766 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.

(RUN 7 10000000) 
(FUNCALL #'RUN WHICH N) took 1,000 milliseconds (1.000 seconds) to run 
                    with 2 available CPU cores.
During that period, 1,000 milliseconds (1.000 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.

(RUN 8 10000000) 
(FUNCALL #'RUN WHICH N) took 1,000 milliseconds (1.000 seconds) to run 
                    with 2 available CPU cores.
During that period, 1,047 milliseconds (1.047 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
 16 bytes of memory allocated.


Run on Dec. 30, 2009.

*features* =>

(:ASDF :PRIMARY-CLASSES :COMMON-LISP :OPENMCL :CCL :CCL-1.2
:CCL-1.3 :CCL-1.4 :CLOZURE :CLOZURE-COMMON-LISP :ANSI-CL
:OPENMCL-UNICODE-STRINGS :OPENMCL-NATIVE-THREADS
:OPENMCL-PARTIAL-MOP :MCL-COMMON-MOP-SUBSET :OPENMCL-MOP-2
:OPENMCL-PRIVATE-HASH-TABLES :X8632-TARGET :X8632-HOST :X86
:X86-TARGET :X86-HOST :WINDOWS-HOST :WINDOWS-TARGET :WIN32-TARGET
:WIN32-HOST :32-BIT-TARGET :32-BIT-HOST :LITTLE-ENDIAN-TARGET
:LITTLE-ENDIAN-HOST :WINDOWS)

Change History (3)

comment:1 Changed 9 years ago by gb

  • Description modified (diff)

comment:2 Changed 8 years ago by rme

We pointlessly call (typep 0 '(integer 0 0)) in the slow cases above, rather than doing something more clever. But "safety 3" and "clever" are two words that have never really gone together.

comment:3 Changed 7 years ago by gb

(In [15518]) In X862-TYPECHECKED-FORM, don't typecheck constants that're of the proper type.

See ticket:638.

Note: See TracTickets for help on using tickets.