>>>>> "Raymond" == Raymond Toy <[EMAIL PROTECTED]> writes:

>>>>> "Raymond" == Raymond Toy <[EMAIL PROTECTED]> writes:
>>>>> "rif" == rif  <[EMAIL PROTECTED]> writes:
    rif> Type-error in KERNEL::OBJECT-NOT-TYPE-ERROR-HANDLER:
    rif> 4145112608 is not of type (UNSIGNED-BYTE 29)

    Raymond> Here is a patch to profile.lisp that allows larger consing to happen.
    Raymond> It's based on Martin's idea of using 2 fixnums to hold the consing
    Raymond> values. 

    Raymond> This seems to work for me.  If you can, try it out and let me know how
    Raymond> it goes.

    Raymond> Let's try that again, as a text file.

Hey, where'd my text/plain attachment go?

One more time, but no attachment---just plain text.

Oh, this patch also changes the output of report-time so that all of
the columns line up neatly, no matter how long they get.

Ray

--- profile.lisp        Wed May  1 13:43:37 2002
+++ new-profile.lisp    Mon Oct 28 09:22:59 2002
@@ -95,7 +95,45 @@
 ;;; since the beginning of time.
 
 #+cmu
-(defmacro total-consing () '(the consing-type (ext:get-bytes-consed)))
+(defmacro total-consing ()
+  '(ext:get-bytes-consed))
+
+(eval-when (compile load eval)
+;; Some macros to implement a very simple "bignum" package consisting
+;; of 2 fixnums.  This is intended to extend the range of the consing
+;; for profiling without adding lots of extra consing to the profiling
+;; routines.
+(defconstant +fixnum-bits+
+  #.(integer-length most-positive-fixnum)
+  "The number of bits in a fixnum")
+
+(defmacro dfix-add ((a-hi a-lo) (b-hi b-lo))
+  ;; Add the 2 fixnums and return the sum as two values
+  (let ((hi (gensym))
+       (lo (gensym)))
+    `(let ((,hi (+ ,a-hi ,b-hi))
+          (,lo (+ ,a-lo ,b-lo)))
+       (if (<= ,lo most-positive-fixnum)
+          (values ,hi ,lo)
+          (values (+ ,hi 1)
+                  (ldb (byte (integer-length most-positive-fixnum) 0)
+                       ,lo))))))
+(defmacro dfix-sub ((a-hi a-lo) (b-hi b-lo))
+  ;; Subtract 2 fixnums and return the difference as two values
+  (let ((hi (gensym))
+       (lo (gensym)))
+    `(let ((,hi (- ,a-hi ,b-hi))
+          (,lo (- ,a-lo ,b-lo)))
+       (if (>= ,lo)
+          (values ,hi ,lo)
+          (values (- ,hi 1)
+                  (+ ,lo #.(1+ most-positive-fixnum)))))))
+  
+(defmacro dfix-incf ((res-hi res-lo) (a-hi a-lo))
+  ;; Like incf, except for pairs of fixnum
+  `(multiple-value-setq (,res-hi ,res-lo)
+     (dfix-add (,res-hi ,res-lo) (,a-hi ,a-lo))))
+)
 
 #-cmu
 (progn
@@ -180,9 +218,10 @@
 ;;;
 (defvar *enclosed-time* 0)
 (defvar *enclosed-consing* 0)
+(defvar *enclosed-consing-hi* 0)
 (defvar *enclosed-profilings* 0)
 (declaim (type time-type *enclosed-time*))
-(declaim (type consing-type *enclosed-consing*))
+(declaim (type consing-type *enclosed-consing* *enclosed-consing-hi*))
 (declaim (fixnum *enclosed-profilings*))
 
 
@@ -226,10 +265,11 @@
        (let* ((time 0)
              (count 0)
              (consed 0)
+             (consed-hi 0)
              (profile 0)
              (callers ())
              (old-definition (fdefinition name)))
-        (declare (type time-type time) (type consing-type consed)
+        (declare (type time-type time) (type consing-type consed consed-hi)
                  (fixnum count))
         (pushnew name *timed-functions*)
 
@@ -262,15 +302,19 @@
                             (setq callers current)
                             (return))))))
                               
-                  (let ((time-inc 0) (cons-inc 0) (profile-inc 0))
+                  (let ((time-inc 0)
+                        (cons-inc 0)
+                        (cons-inc-hi 0)
+                        (profile-inc 0))
                     (declare (type time-type time-inc)
-                             (type consing-type cons-inc)
+                             (type consing-type cons-inc cons-inc-hi)
                              (fixnum profile-inc))
                     (multiple-value-prog1
                         (let ((start-time (quickly-get-time))
                               (start-consed (total-consing))
                               (*enclosed-time* 0)
                               (*enclosed-consing* 0)
+                              (*enclosed-consing-hi* 0)
                               (*enclosed-profilings* 0))
                           (multiple-value-prog1
                               ,(if optionals-p
@@ -290,7 +334,11 @@
                                   (- (quickly-get-time) start-time)
                                   #+BSD
                                   (max (- (quickly-get-time) start-time) 0))
-                            (setq cons-inc (- (total-consing) start-consed))
+                            (multiple-value-setq (cons-inc-hi cons-inc)
+                              (let ((diff (- (total-consing) start-consed)))
+                                (values (ash diff #.(- (integer-length 
+most-positive-fixnum)))
+                                        (ldb (byte 29 0) diff))))
+
                             (setq profile-inc *enclosed-profilings*)
                             (incf time
                                   (the time-type
@@ -298,12 +346,18 @@
                                        (- time-inc *enclosed-time*)
                                        #+BSD
                                        (max (- time-inc *enclosed-time*) 0)))
-                            (incf consed
-                                  (the consing-type
-                                       (- cons-inc *enclosed-consing*)))
+                            ;; consed = consed + (- cons-inc *enclosed-consing*)
+                            (multiple-value-bind (dhi dlo)
+                                (dfix-sub (cons-inc-hi cons-inc)
+                                          (*enclosed-consing-hi* *enclosed-consing*))
+
+                              (dfix-incf (consed-hi consed) (dhi dlo)))
+
                             (incf profile profile-inc)))
                       (incf *enclosed-time* time-inc)
-                      (incf *enclosed-consing* cons-inc)
+                      ;; *enclosed-consing* = *enclosed-consing + cons-inc
+                      (dfix-incf (*enclosed-consing-hi* *enclosed-consing*)
+                                 (cons-inc-hi cons-inc))
                       (incf *enclosed-profilings*
                             (the fixnum (1+ profile-inc)))))))
         
@@ -314,12 +368,14 @@
                :new-definition (fdefinition name)
                :read-time
                #'(lambda ()
-                   (values count time consed profile callers))
+                   (let ((total-cons (+ consed (ash consed-hi 30))))
+                     (values count time total-cons profile callers)))
                :reset-time
                #'(lambda ()
                    (setq count 0)
                    (setq time 0)
                    (setq consed 0)
+                   (setq consed-hi 0)
                    (setq profile 0)
                    (setq callers ())
                    t)))))))
@@ -474,6 +530,67 @@
     (if (minusp compensated) 0.0 compensated)))
 
 
+#+nil
+(defun compute-widths (info)
+  (let ((total-time (reduce #'+ info :key #'time-info-time))
+       (total-cons (reduce #'+ info :key #'time-info-consing))
+       (total-calls (reduce #'+ info :key #'time-info-calls))
+       (max-time/call
+        (reduce #'max info :key #'(lambda (x)
+                                    (/ (time-info-time x)
+                                       (float (time-info-calls x))))))
+       (cons-length 0))
+    (setq cons-length (ceiling (log total-cons 10)))
+    (incf cons-length (floor (log total-cons 10) 3))
+    (values total-time
+           total-cons
+           total-calls
+           (+ 3 (max 7 (ceiling (log total-time 10))))
+           (max 9 cons-length)
+           (max 7 (ceiling (log total-calls 10)))
+           (+ 5 (max 5 (ceiling (log max-time/call 10)))))))
+
+;; Compute and return the total time, total cons, total-calls, and the
+;; width of the field needed to hold the total time, total cons,
+;; total-calls, and the max time/call.
+
+(defun compute-totals-and-widths (info)
+  (let ((total-time 0)
+       (total-cons 0)
+       (total-calls 0)
+       (max-time/call 0))
+    ;; Find the total time, total consing, total calls, and the max
+    ;; time/call
+    (dolist (item info)
+      (let ((time (time-info-time item)))
+       (incf total-time time)
+       (incf total-cons (time-info-consing item))
+       (incf total-calls (time-info-calls item))
+       (setf max-time/call (max max-time/call
+                                (/ time (float (time-info-calls item)))))))
+
+    ;; Figure out the width needed for total-time, total-cons,
+    ;; total-calls and the max-time/call.  The total-cons is more
+    ;; complicated because we print the consing with comma
+    ;; separators. For total-time, we assume a default of "~10,3F";
+    ;; for total-calls, "~7D"; for time/call, "~10,5F".  This is where
+    ;; the constants come from.
+    (flet ((safe-log10 (x)
+            ;; log base 10 of x, but any non-positive value for
+            ;; log10(x) is ok for what we want.
+            (if (zerop x)
+                0.0
+                (log x 10))))
+      (let ((cons-length (ceiling (safe-log10 total-cons))))
+       (incf cons-length (floor (safe-log10 total-cons) 3))
+       (values total-time
+               total-cons
+               total-calls
+               (+ 3 (max 7 (ceiling (safe-log10 total-time))))
+               (max 9 cons-length)
+               (max 7 (ceiling (safe-log10 total-calls)))
+               (+ 5 (max 5 (ceiling (safe-log10 max-time/call)))))))))
+
 (defun %report-times (names)
   (declare (optimize (speed 0)))
   (unless (boundp '*call-overhead*)
@@ -488,7 +605,7 @@
                 PROFILE it again to record calls to the new definition."
                name))
        (multiple-value-bind
-           (calls time consing profile callers)
+             (calls time consing profile callers)
            (funcall (profile-info-read-time pinfo))
          (if (zerop calls)
              (push name *no-calls*)
@@ -501,22 +618,29 @@
     
     (setq info (sort info #'>= :key #'time-info-time))
 
-    (format *trace-output*
-           "~&  Seconds  |  Consed   |  Calls  |  Sec/Call  |  Name:~@
-              ------------------------------------------------------~%")
-
-    (let ((total-time 0.0)
-         (total-consed 0)
-         (total-calls 0))
+    (multiple-value-bind (total-time total-consed total-calls
+                                    time-width cons-width calls-width
+                                    time/call-width)
+       (compute-widths info)
+
+      (format *trace-output*
+             "~& ~V@A| ~V@A | ~V@A | ~V@A | Name:~@
+              ------------------------------------------------------~%"
+             time-width "Seconds"
+             cons-width "Consed"
+             calls-width "Calls"
+             time/call-width "Sec/Call")
+
       (dolist (time info)
-       (incf total-time (time-info-time time))
-       (incf total-calls (time-info-calls time))
-       (incf total-consed (time-info-consing time))
        (format *trace-output*
-               "~10,3F | ~9:D | ~7:D | ~10,5F | ~S~%"
+               "~V,3F | ~V:D | ~V:D | ~V,5F | ~S~%"
+               time-width
                (time-info-time time)
+               cons-width
                (time-info-consing time)
+               calls-width
                (time-info-calls time)
+               time/call-width
                (/ (time-info-time time) (float (time-info-calls time)))
                (time-info-name time))
        (let ((callers (time-info-callers time)))
@@ -528,8 +652,11 @@
            (terpri *trace-output*))))
       (format *trace-output*
              "------------------------------------------------------~@
-             ~10,3F | ~9:D | ~7:D |            | Total~%"
-             total-time total-consed total-calls)
+             ~V,3F | ~V:D | ~V:D | ~VA | Total~%"
+             time-width total-time
+             cons-width total-consed
+             calls-width total-calls
+             time/call-width " ")
 
       (format *trace-output*
              "~%Estimated total profiling overhead: ~4,2F seconds~%"

Reply via email to