Skip to content
timing.lisp 6.98 KiB
Newer Older
Raymond Toy's avatar
Raymond Toy committed
;;;; -*- Mode: lisp -*-
;;;;
;;;; Copyright (c) 2007 Raymond Toy
;;;;
;;;; Permission is hereby granted, free of charge, to any person
;;;; obtaining a copy of this software and associated documentation
;;;; files (the "Software"), to deal in the Software without
;;;; restriction, including without limitation the rights to use,
;;;; copy, modify, merge, publish, distribute, sublicense, and/or sell
;;;; copies of the Software, and to permit persons to whom the
;;;; Software is furnished to do so, subject to the following
;;;; conditions:
;;;;
;;;; The above copyright notice and this permission notice shall be
;;;; included in all copies or substantial portions of the Software.
;;;;
;;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
;;;; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
;;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
;;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
;;;; OTHER DEALINGS IN THE SOFTWARE.


;;; Some simple timing tests
(in-package #:oct)
Raymond Toy's avatar
Raymond Toy committed

(defun time-add (&optional (n 100000))
  (declare (fixnum n))
  (flet ((sum-double ()
	   (let ((sum 0d0))
	     (declare (double-float sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (cl:+ sum 1d0)))
	     sum))
	 (sum-%qd ()
	   (let ((sum (octi::make-qd-d 0d0))
		 (one (octi::make-qd-d 1d0)))
	     (declare (type octi::%quad-double sum)
Raymond Toy's avatar
Raymond Toy committed
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (add-qd sum one)))
	     sum))
	 (sum-qd ()
	   (let ((sum #q0))
	     (declare (type qd-real sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (+ sum #q1)))
	     sum)))
    (format t "Add double-floats ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (sum-double))
    (format t "Add %quad-double (internal) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (sum-%qd))
    (format t "Add QD-REAL (method) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (sum-qd))))


(defun time-mul (&optional (n 100000))
  (declare (fixnum n))
  (flet ((mul-double ()
	   (let ((sum 0d0))
	     (declare (double-float sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (cl:* sum 1d0)))
	     sum))
	 (mul-%qd ()
	   (let ((sum (octi::make-qd-d 0d0))
		 (one (octi::make-qd-d 1d0)))
	     (declare (type octi::%quad-double sum)
Raymond Toy's avatar
Raymond Toy committed
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (mul-qd sum one)))
	     sum))
	 (mul-qd ()
	   (let ((sum #q0))
	     (declare (type qd-real sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (* sum #q1)))
	     sum)))
    (format t "Multiply double-floats ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (mul-double))
    (format t "Multiply %quad-double (internal) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (mul-%qd))
    (format t "Multiply QD-REAL (method) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (mul-qd))))

(defun time-div (&optional (n 100000))
  (declare (fixnum n))
  (flet ((div-double ()
	   (let ((sum 7d0))
	     (declare (double-float sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (cl:/ sum 1d0)))
	     sum))
	 (div-%qd ()
	   (let ((sum (octi::make-qd-d 7d0))
		 (one (octi::make-qd-d 1d0)))
	     (declare (type octi::%quad-double sum)
Raymond Toy's avatar
Raymond Toy committed
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (div-qd sum one)))
	     sum))
	 (div-qd ()
	   (let ((sum #q7))
	     (declare (type qd-real sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (/ sum #q1)))
	     sum)))
    (format t "Divide double-floats ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (div-double))
    (format t "Divide %quad-double (internal) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (div-%qd))
    (format t "Divide QD-REAL (method) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (div-qd))))

(defun time-sqrt (&optional (n 100000))
  (declare (fixnum n))
  (flet ((sqrt-double ()
	   (let ((sum 7d0))
	     (declare (double-float sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (cl:sqrt sum)))
	     sum))
	 (sqrt-%qd ()
	   (let ((sum (octi::make-qd-d 7d0)))
	     (declare (type octi::%quad-double sum)
Raymond Toy's avatar
Raymond Toy committed
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (sqrt-qd sum)))
	     sum))
	 (sqrt-qd-real ()
	   (let ((sum #q7))
	     (declare (type qd-real sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (sqrt sum)))
	     sum)))
    (format t "Sqrt double-floats ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (sqrt-double))
    (format t "Sqrt %quad-double (internal) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (sqrt-%qd))
    (format t "Sqrt QD-REAL (method) ~d times~%" n)
    #+cmu (ext:gc :full t)
    (time (sqrt-qd-real))))

(defun time-atan (&optional (n 10000))
  (declare (fixnum n))
  (flet ((time-atan/newton ()
	   (let ((sum (octi::make-qd-d 0.01d0)))
	     (declare (type octi::%quad-double sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (octi::atan-qd/newton sum)))
	     sum))
	 (time-atan/taylor ()
	   (let ((sum (octi::make-qd-d 0.01d0)))
	     (declare (type octi::%quad-double sum)
		      (optimize (speed 3)))
	     (dotimes (k n)
	       (declare (fixnum k))
	       (setf sum (octi::atan-qd/taylor sum)))
	     sum)))
    (format t "atan-qd/newton ~d times~%" n)
    #+cmu (ext:gc :full t)
    (format t "sum = ~A~%" (time (time-atan/newton)))
    (format t "atan-qd/taylor ~d times~%" n)
    #+cmu (ext:gc :full t)
    (format t "sum = ~A~%" (time (time-atan/taylor)))))

;; Some timing results on an iMac, 3.06 GHz Core i3:

; atan-qd/newton 10000 times

; Evaluation took:
;   6.15 seconds of real time
;   6.116626 seconds of user run time
;   0.021624 seconds of system run time
;   18,805,071,897 CPU cycles
;   [Run times include 0.24 seconds GC run time]
;   0 page faults and
;   893,037,112 bytes consed.
; 
; sum = #C(0.0077459785628163552318041722744135w0 5.8166227464838760117515984152653w-36)
;
; atan-qd/taylor 10000 times

; Evaluation took:
;   0.29 seconds of real time
;   0.28987 seconds of user run time
;   0.001629 seconds of system run time
;   892,698,785 CPU cycles
;   [Run times include 0.02 seconds GC run time]
;   0 page faults and
;   79,108,384 bytes consed.
; 
; sum = #C(0.0077459785628163552318041722744135w0 5.81662274648387601175165266362535w-36)

;; We see that the taylor series is 21 times faster (!) and conses 11
;; times less.  That's a pretty nice gain, at the expense of two
;; 1024-element tables.