<div dir="ltr"><span style="color:rgb(0,0,0);font-family:helvetica;font-size:12px">SBCL shouldn’t cons even if you are using full 64 bits (with proper declaration) … except that bignum needs to be allocated as result.</span><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 5, 2017 at 1:16 AM, Shannon Spires <span dir="ltr"><<a href="mailto:svs@bearlanding.com" target="_blank">svs@bearlanding.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Very interesting. So let's normalize things. Looks like you're seeing about (/ 3.<a href="tel:(214)%20748-3647" value="+12147483647" target="_blank">1 2147483647</a>) = 1.4 ns per addition in SBCL <div>and about (/ 48.3 <a href="tel:(214)%20748-3647" value="+12147483647" target="_blank">2147483647</a>) = 22.5 ns per addition in CCL.<br><div><div><br></div><div>Note that your original total, <span class="m_571292361341230833Apple-style-span" style="font-family:'Courier New'">2305843005992468481,</span> is a fixnum in SBCL but not in CCL.</div><div><span class="m_571292361341230833Apple-style-span" style="font-family:'Courier New'"><br></span></div><div><span class="m_571292361341230833Apple-style-span" style="font-family:'Courier New'"><div style="font-family:Palatino">In CCL, most-positive-fixnum is (- (expt 2 60) 1).</div><div style="font-family:Palatino">In SBCL, most-positive-fixnum is (- (expt 2 62) 1). So a fixnum is 2 bits larger in SBCL.</div><div><br></div></span></div><div>Knowing that the sum of numbers from 0..n is (/ (* n (1+ n)) 2), and here n = <a href="tel:(214)%20748-3646" value="+12147483646" target="_blank">2147483646</a>, we know how to limit the sum to be a fixnum. If we set the loop limit to <span class="m_571292361341230833Apple-style-span" style="font-family:Courier">(truncate (sqrt most-positive-fixnum))</span></div><div>it's a quick and dirty way to be even more conservative than the true limit given by the quadratic formula.</div><div><br></div><div>If I rewrite the CCL code such that sum is guaranteed to be a fixnum it's much faster:</div><div><br></div><div><span class=""><div><font class="m_571292361341230833Apple-style-span" face="Courier">(defun sum-test-iterative ()</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  (declare (optimize speed (safety 0)))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  (let ((sum 0))</font></div></span><div><font class="m_571292361341230833Apple-style-span" face="Courier">    (declare (fixnum sum))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">    (dotimes (i (truncate (sqrt most-positive-fixnum)))</font></div><span class=""><div><font class="m_571292361341230833Apple-style-span" face="Courier">      (setf sum  (+ sum i)))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  sum))</font></div></span></div><div><font class="m_571292361341230833Apple-style-span" face="Courier"><br></font></div><div><div><font class="m_571292361341230833Apple-style-span" face="Courier">? (time (SUM-TEST-ITERATIVE))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">(SUM-TEST-ITERATIVE)</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">took 5,061,389 microseconds (5.061389 seconds) to run.</font></div><span class=""><div><font class="m_571292361341230833Apple-style-span" face="Courier">During that period, and with 4 available CPU cores,</font></div></span><div><font class="m_571292361341230833Apple-style-span" face="Courier">     5,077,467 microseconds (5.077467 seconds) were spent in user mode</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">         6,632 microseconds (0.006632 seconds) were spent in system mode</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">576460751766552576</font></div></div><div><br></div><div>This is about (/ 5.0 (truncate (sqrt most-positive-fixnum))) = 4.7 ns per addition.</div><div><br></div><div>If I add two characters ( #. ), it becomes 2x faster still:</div><div><br></div><div><span class=""><div><font class="m_571292361341230833Apple-style-span" face="Courier">(defun sum-test-iterative ()</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  (declare (optimize speed (safety 0)))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  (let ((sum 0))</font></div></span><div><font class="m_571292361341230833Apple-style-span" face="Courier">    (declare (fixnum sum))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">    (dotimes (i #.(truncate (sqrt most-positive-fixnum)))  ; (declare (fixnum i)) works here too, without the #.</font></div><span class=""><div><font class="m_571292361341230833Apple-style-span" face="Courier">      (setf sum  (+ sum i)))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  sum))</font></div></span></div><div><font class="m_571292361341230833Apple-style-span" face="Courier"><br></font></div><div><div><div><font class="m_571292361341230833Apple-style-span" face="Courier">? (time (SUM-TEST-ITERATIVE))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">(SUM-TEST-ITERATIVE)</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">took 2,342,141 microseconds (2.342141 seconds) to run.</font></div><span class=""><div><font class="m_571292361341230833Apple-style-span" face="Courier">During that period, and with 4 available CPU cores,</font></div></span><div><font class="m_571292361341230833Apple-style-span" face="Courier">     2,355,535 microseconds (2.355535 seconds) were spent in user mode</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">         2,729 microseconds (0.002729 seconds) were spent in system mode</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">576460751766552576</font></div></div></div><div><br></div><div><div>This is about (/ 2.3 (truncate (sqrt most-positive-fixnum))) = 2.1 ns per addition.</div></div><div><br></div><div>The last function above in SBCL:</div><div><font class="m_571292361341230833Apple-style-span" face="Courier">* (time (sum-test-iterative))</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier"><br></font></div><div><div><font class="m_571292361341230833Apple-style-span" face="Courier">Evaluation took:</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  1.182 seconds of real time</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  1.180927 seconds of total run time (1.179539 user, 0.001388 system)</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  99.92% CPU</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  3,184,332,795 processor cycles</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  0 bytes consed</font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">  </font></div><div><font class="m_571292361341230833Apple-style-span" face="Courier">2305843008139952128</font></div></div><div><br></div><div>This is about (/ 1.18 (truncate (sqrt most-positive-fixnum))) = 0.5 ns per addition which is close to one add per clock cycle on my 2.7 GHz machine. This is C-level speed, but it's only 4x faster than CCL if we keep everybody in the fixnum domain. I'd still like to know why CCL is 4x slower, but at least now we're comparing apples-to-apples.</div><div><br></div><div>-SS</div><div><div class="h5"><div><br></div><div>On May 4, 2017, at 2:26 PM, Jonathan Fischer wrote:</div><br class="m_571292361341230833Apple-interchange-newline"></div></div><blockquote type="cite"><div><div class="h5"><div style="word-wrap:break-word">This is a stupid thing to test, I was just curious about it, and I’m wondering what obvious thing it is I’m doing wrong to get really bad results.<div><br></div><div>For starters, a silly little function to sum up an arithmetic series:</div><div><br></div><div><div><font face="Courier New">(defun sum-test-iterative ()</font></div><div><font face="Courier New">  (let ((sum 0))</font></div><div><font face="Courier New">    (dotimes (i <a href="tel:(214)%20748-3647" value="+12147483647" target="_blank">2147483647</a>)</font></div><div><font face="Courier New">      (setf sum (+ sum i)))</font></div><div><font face="Courier New">    sum))</font></div></div><div><br></div><div>In ClozureCL 1.11, this is horribly slow and conses like crazy:</div><div><br></div><div><font face="Courier New">? (time (sum-test-iterative))<br>(SUM-TEST-ITERATIVE)<br>took 62,875,836 microseconds (62.875835 seconds) to run.<br>      2,818,179 microseconds ( 2.818179 seconds, 4.48%) of which was spent in GC.<br>During that period, and with 4 available CPU cores,<br>     55,949,019 microseconds (55.949020 seconds) were spent in user mode<br>      7,153,305 microseconds ( 7.153305 seconds) were spent in system mode<br> 20,127,468,688 bytes of memory allocated.<br> 10,397 minor page faults, 8 major page faults, 0 swaps.<br>2305843005992468481</font></div><div><br></div><div>SBCL 1.3.17 does much better:</div><div><br></div><div><font face="Courier New">* (time (sum-test-iterative))<br><br>Evaluation took:<br>  7.741 seconds of real time<br>  7.677832 seconds of total run time (7.594504 user, 0.083328 system)<br>  99.19% CPU<br>  18,536,585,073 processor cycles<br>  0 bytes consed<br>  <br>2305843005992468481<br></font><br></div><div>If I sprinkle in some declarations I can get SBCL down to a bit over 3 seconds, but ClozureCL’s still pretty bad:</div><div><br></div><div><font face="Courier New">(defun sum-test-iterative ()<br>  (declare (optimize speed (safety 0)))<br>  (let ((sum 0))<br>    (declare ((signed-byte 64) sum))<br>    (dotimes (i <a href="tel:(214)%20748-3647" value="+12147483647" target="_blank">2147483647</a>)<br>      (setf sum (the (signed-byte 64) (+ sum i))))<br>    sum))</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">? (time (sum-test-iterative))<br>(SUM-TEST-ITERATIVE)<br>took 48,308,393 microseconds (48.308390 seconds) to run.<br>      2,875,113 microseconds ( 2.875113 seconds, 5.95%) of which was spent in GC.<br>During that period, and with 4 available CPU cores,<br>     42,849,312 microseconds (42.849310 seconds) were spent in user mode<br>      6,040,092 microseconds ( 6.040092 seconds) were spent in system mode<br> 20,127,468,707 bytes of memory allocated.<br> 14,039 minor page faults, 1 major page faults, 0 swaps.<br>2305843005992468481</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">* (time (sum-test-iterative))<br><br>Evaluation took:<br>  3.267 seconds of real time<br>  3.248668 seconds of total run time (3.228591 user, 0.020077 system)<br>  99.45% CPU<br>  7,821,424,512 processor cycles<br>  0 bytes consed<br>  <br>2305843005992468481<br></font><br></div><div>How can I help ClozureCL out here? Both of these are running 64-bit on macOS, btw.</div></div></div></div>______________________________<wbr>_________________<br>Openmcl-devel mailing list<br><a href="mailto:Openmcl-devel@clozure.com" target="_blank">Openmcl-devel@clozure.com</a><br><a href="https://lists.clozure.com/mailman/listinfo/openmcl-devel" target="_blank">https://lists.clozure.com/<wbr>mailman/listinfo/openmcl-devel</a><br></blockquote></div><br></div></div><br>______________________________<wbr>_________________<br>
Openmcl-devel mailing list<br>
<a href="mailto:Openmcl-devel@clozure.com">Openmcl-devel@clozure.com</a><br>
<a href="https://lists.clozure.com/mailman/listinfo/openmcl-devel" rel="noreferrer" target="_blank">https://lists.clozure.com/<wbr>mailman/listinfo/openmcl-devel</a><br>
<br></blockquote></div><br></div>