Newer
Older
;;;; -*- 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.
;;; Here are some simple timing tests, based on Yozo Hida's qd_timer
;;; test code. I've tried to make these versions time the same
;;; operations as Yozo's.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
(defun time-add (&optional (n 100000))
(declare (fixnum n)
(optimize (speed 3)))
(let ((a (/ #q7))
(b #q0))
(declare (type qd-real a b))
(time (dotimes (k n)
(declare (fixnum k))
(incf b a)))
(format t "n = ~D~%" n)
(format t "b = ~W~%" b)))
(defun time-mul (&optional (n 100000))
(declare (fixnum n)
(optimize (speed 3)))
(let ((a (+ 1 (/ (float n #q1))))
(b #q1))
(declare (type qd-real a b))
(time (dotimes (k n)
(declare (fixnum k))
(setf b (* a b))))
(format t "n = ~D~%" n)
(format t "b = ~W~%" b)))
(defun time-div (&optional (n 100000))
(declare (fixnum n)
(optimize (speed 3)))
(let ((a (+ 1 (/ (float n #q1))))
(b #q1))
(declare (type qd-real a b))
(time (dotimes (k n)
(declare (fixnum k))
(setf b (/ b a))))
(format t "n = ~D~%" n)
(format t "b = ~W~%" b)))
(defun time-sqrt (&optional (n 100000))
(declare (fixnum n)
(optimize (speed 3)))
(let ((a #q0)
(b (+ 2 +pi+)))
(declare (type qd-real a b))
(time (dotimes (k n)
(declare (fixnum k))
(setf a (sqrt (+ a b)))))
(format t "n = ~D~%" n)
(format t "a = ~W~%" a)))
(defun time-sin (&optional (n 2000))
(declare (fixnum n)
(optimize (speed 3)))
(let ((a #q0)
(b (/ +pi+ n))
(c #q0))
(declare (type qd-real a b c))
(time (dotimes (k n)
(declare (fixnum k))
(incf a b)
(incf c (sin a))))
(format t "n = ~D~%" n)
(format t "a = ~W~%" a)))
(defun time-log (&optional (n 1000))
(declare (fixnum n)
(optimize (speed 3)))
(let ((a #q0)
(c (exp #q-50.1))
(d (exp (/ #q100.2 n))))
(declare (type qd-real a c d))
(time (dotimes (k n)
(declare (fixnum k))
(incf a (log c))
(setf c (* c d))))
(format t "n = ~D~%" n)
(format t "a = ~W~%" a)))
#||
Some test results. These were all run on a Sun Blade 1500 using a 1.5
GHz Ultrasparc III. I used the default configuration when compiling
qd, and used Sun's C++ compiler with -O. For the Lisp timing, I used
CMUCL.
Executive summary:
Test Time
qd oct
---- -----------
add 0.23 1.16
mul 0.749 1.54
div 3.00 3.11
sqrt 10.57 12.2
sin 57.33 64.5
log 194 119
Times are in microsec/operation for the test. The default number of
iterations were used. Most of the timings match my expectations,
including the log test. Oct uses a different algorithm (Halley's
method) which is faster (in Lisp) than the algorithm used in qd
(Newtwon iteration).
Not also that these times include the 3-arg versions of the routines.
-------------------------------------------------------------------------------
The raw data:
The output from qd_timer -qd -v:
Timing qd_real
--------------
n = 1000000 t = 0.236154
b = 142857.142857
1000000 operations in 0.236154 s.
0.236154 us
n = 1000000 t = 0.748933
b = 2.718280
1000000 operations in 0.748933 s.
0.748933 us
n = 1000000 t = 3.004328
b = 0.367880
1000000 operations in 3.004328 s.
3.004328 us
n = 100000 t = 1.057170
100000 operations in 1.057170 s.
10.571696 us
n = 20000 t = 1.146667
20000 operations in 1.146667 s.
57.333335 us
n = 10000 t = 1.939869
10000 operations in 1.939869 s.
193.986900 us
--------------------------------------------------
CMUCL results:
CL-USER> (oct::time-add 1000000)
; 1.16 seconds of real time
; 0.98 seconds of user run time
; 0.18 seconds of system run time
; 1,845,637,904 CPU cycles
; 72,000,248 bytes consed.
n = 1000000
b = #q142857.142857142857142857142857142857142857142857142857142857142854q0
CL-USER> (oct::time-mul 1000000)
; 1.53 seconds of real time
; 1.27 seconds of user run time
; 0.25 seconds of system run time
; 2,430,859,732 CPU cycles
; 72,000,248 bytes consed.
n = 1000000
b = #q2.71828046931937688381979970845435639275164502668250771294016782123q0
CL-USER> (oct::time-div 1000000)
; 3.11 seconds of real time
; 2.94 seconds of user run time
; 0.16 seconds of system run time
; 4,957,512,968 CPU cycles
; 72,000,248 bytes consed.
n = 1000000
b = #q0.367879625111086265804761271038216553876450599098470428879260437304q0
CL-USER> (oct::time-sqrt 100000)
; 1.22 seconds of real time
; 1.1 seconds of user run time
; 0.1 seconds of system run time
; 1,938,798,996 CPU cycles
; 24,000,128 bytes consed.
a = #q2.82198033014704783016853125515542796898998765943212617578596649019q0
CL-USER> (oct::time-sin 20000)
; 1.29 seconds of real time
; 1.24 seconds of user run time
; 0.05 seconds of system run time
; 2,053,157,408 CPU cycles
; 27,751,144 bytes consed.
n = 20000
a = #q3.14159265358979323846264338327950288419716939937510582097494458294q0
CL-USER> (oct::time-log 10000)
; 1.19 seconds of real time
; 1.13 seconds of user run time
; 0.04 seconds of system run time
; 1,890,677,952 CPU cycles
; 16,197,536 bytes consed.
n = 10000
a = #q-50.100000000000000000000000000000000000000000000000000000552824575q0