<br><br><div class="gmail_quote">On Sun, Jul 10, 2011 at 5:06 AM, Levente Uzonyi <span dir="ltr">&lt;<a href="mailto:leves@elte.hu">leves@elte.hu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I read the JIT code (#genSmallIntegerComparison:) and found that it doesn&#39;t implement the 4-byte LargePositiveInteger checks. So the code behaves differently when it&#39;s interpreted and when it&#39;s jitted:<br>
<br>
(1 to: 2) collect: [ :each | 0 = (LargePositiveInteger new: 4) ].<br>
<br>
gives<br>
<br>
#(true false).<br>
<br>
But this is not a real problem IMHO, because the argument is not normalized. How hard would it be to implement the support for LargePositiveIntegers in the JIT-ed code?<br></blockquote><div><br></div><div>Quite easy.  The failure path would be modified to invoke the interpreter primitives.  I had not done so on minimalism grounds in that I had wanted to get things working fast for the common case asap.  I have a slight antipathy to the normal Squeak code which only copes with integers up to 64-bits.  But Cog includes the LargeIntegersPlugin <font class="Apple-style-span" face="arial, helvetica, sans-serif">by </font><font class="Apple-style-span" face="arial, helvetica, sans-serif">Stephan Rudlof, and this is probably the best code to fall back on.</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">Regarding implementation, arguably fast failure is important (since inequality can be important to establish too) so, since LargeNegativeInteger, LargePositiveInteger and Float all have contiguous compact class indices the code could be something of the flavour of</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">    SmallInteger = (assume the receiver is a SmallInteger)</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif">        arg isSmallInteger ifTrue:</font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">            [....inline code for SmallInteger comparison].</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif">        compactClassIndex := arg compactClassIndex.</font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">        (compactClassIndex &gt;= ClassLargeNegativeIntegerCompactIndex</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif">        and: [</font><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif; ">compactClassIndex &lt;= ClassFloatCompactIndex]) ifTrue:</span></div>
<div><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif; ">            [</span><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif; ">compactClassIndex &lt;= ClassLargePositiveIntegerCompactIndex ifTrue:</span></div>
<div><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif; ">                  [call corresponding primitive in the LargeIntegersPlugin].</span></div><div><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif; ">             inline code for SmallInteger x Float comparison]</span></div>
<div><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif; ">        fail</span></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif"> </font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">and of course this pattern could apply to comparison operations and arithmetic.  For little extra cost the code could also include a test for the receiver being a SmallInteger, but IMO its better to have primitives that are specific to the receiver (for performance) and have the VM implement primitives for SmallInteger Large{Posi,Nega}tiveInteger &amp; Float than have one size fits all.</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">2¢</font></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888">
<br>
<br>
Levente<br>
</font><br>
P.S.: Sorry for still nagging about this.<div><div></div><div class="h5"><br>
<br>
On Sun, 10 Jul 2011, Levente Uzonyi wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I fired up QVMProfiler (hacked it a bit to make it work again under windows). Integer &gt;&gt; #= is invoked during execution, even though it can&#39;t be seen from the debugger. Here&#39;s the VM report for the old version:<br>

<br>
gc prior.  clear prior.<br>
2.393 seconds; sampling frequency 998 hz<br>
2389 samples in the VM  (2389 samples in the entire program)  100.0% of total<br>
<br>
799 samples in generated vm code 33.44% of entire vm (33.44% of total)<br>
1590 samples in vanilla vm code 66.56% of entire vm (66.56% of total)<br>
<br>
% of generated vm code (% of total) (samples) (cumulative)<br>
29.91%    (10.00%)      SmallInteger&gt;&gt;=                                 (239) (29.91%)<br>
18.40%    (  6.15%)     Integer&gt;&gt;= (147)        (48.31%)<br>
10.64%    (  3.56%)     UndefinedObject&gt;&gt;DoIt                   (85) (58.95%)<br>
 8.76%    (  2.93%)     Integer&gt;&gt;digitCompare:                  (70) (67.71%)<br>
 8.01%    (  2.68%)     Number&gt;&gt;negative (64)           (75.72%)<br>
 7.63%    (  2.55%)     cePrimReturnEnterCogCode                (61) (83.35%)<br>
 3.38%    (  1.13%)     PIC isInteger (27)              (86.73%)<br>
 3.00%    (  1.00%)     SmallInteger&gt;&gt;&lt;                                 (24) (89.74%)<br>
 2.75%    (  0.92%)     PIC digitCompare: (22)          (92.49%)<br>
 2.63%    (  0.88%)     PIC negative (21)               (95.12%)<br>
 2.50%    (  0.84%)     PIC isNumber (20)               (97.62%)<br>
 1.75%    (  0.59%)     PIC negative (14)               (99.37%)<br>
 0.38%    (  0.13%)     Integer&gt;&gt;isInteger (3)          (99.75%)<br>
 0.13%    (  0.04%)     LargePositiveInteger&gt;&gt;negative  (1) (99.87%)<br>
 0.13%    (  0.04%)     Number&gt;&gt;isNumber                                (1) (100.0%)<br>
<br>
<br>
% of vanilla vm code (% of total) (samples) (cumulative)<br>
31.26%    (20.80%)      _classNameOfIs                  (497)   (31.26%)<br>
13.84%    (  9.21%)     _stSizeOf                                       (220) (45.09%)<br>
11.07%    (  7.37%)     _lengthOf                                       (176) (56.16%)<br>
 9.69%    (  6.45%)     _isWordsOrBytesNonInt   (154)   (65.85%)<br>
 8.18%    (  5.44%)     _isKindOf                                       (130) (74.03%)<br>
 7.04%    (  4.69%)     _arrayValueOf                           (112) (81.07%)<br>
 6.35%    (  4.23%)     _primDigitCompare                       (101) (87.42%)<br>
 6.23%    (  4.14%)     _stackValue                             (99) (93.65%)<br>
 3.14%    (  2.09%)     _popthenPush                            (50) (96.79%)<br>
 1.51%    (  1.00%)     _failed                                         (24) (98.30%)<br>
 1.32%    (  0.88%)     _success                                        (21) (99.62%)<br>
 0.38%    (  0.25%)     _integerObjectOf                        (6) (100.0%)<br>
<br>
And here&#39;s the same report with the new version of Integer &gt;&gt; #=:<br>
<br>
gc prior.  clear prior.<br>
0.169 seconds; sampling frequency 994 hz<br>
168 samples in the VM   (168 samples in the entire program)  100.0% of total<br>
<br>
168 samples in generated vm code 100.0% of entire vm (100.0% of total)<br>
0 samples in vanilla vm code   0.00% of entire vm (  0.00% of total)<br>
<br>
% of generated vm code (% of total)                             (samples) (cumulative)<br>
45.24%    (45.24%)      Integer&gt;&gt;=                                      (76) (45.24%)<br>
25.00%    (25.00%)      SmallInteger&gt;&gt;=                 (42) (70.24%)<br>
18.45%    (18.45%)      PIC isInteger                           (31) (88.69%)<br>
 8.93%    (  8.93%)     UndefinedObject&gt;&gt;DoIt   (15)            (97.62%)<br>
 2.38%    (  2.38%)     Integer&gt;&gt;isInteger                      (4) (100.0%)<br>
<br>
The new version is faster, because it avoids Integer &gt;&gt; #digitCompare: as I expected. But why is Integer &gt;&gt; #= invoked at all? Why can&#39;t it be seen from the debugger?<br>
<br>
<br>
Levente<br>
<br>
<br>
On Sat, 9 Jul 2011, Levente Uzonyi wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Eliot,<br>
<br>
I found that Cog is really slow when I compare SmallIntegers with 4-byte LargePositiveIntegers. In theory this kind of comparison should only be slightly slower than SmallInteger-SmallInteger comparisons, but that&#39;s not the case.<br>

<br>
With Cog (r2434 on windows) I get:<br>
<br>
evaluator := [ :aBlock |<br>
        (((1 to: 5) collect: [ :run |<br>
                aBlock timeToRun ]) sort copyFrom: 2 to: 4) average asFloat ].<br>
evaluator value: [ 1 to: 1000000 do: [ :i | 0 = 1 ] ]. &quot;3.0&quot;<br>
evaluator value: [ 1 to: 1000000 do: [ :i | 0 = 16r40000000 ] ]. &quot;244.0&quot;<br>
<br>
The same code with the Interpreter VM gives 22.0 and 74.0.<br>
<br>
I tried debugging the 0 = 16r40000000 expression with Cog, but the debugger doesn&#39;t touch any smalltalk code during the execution of #=.<br>
If I replace the implementation of Integer &gt;&gt; #= to:<br>
<br>
= aNumber<br>
<br>
        aNumber isInteger ifTrue: [<br>
                aNumber class == self class ifFalse: [ ^false ].<br>
                ^(self digitCompare: aNumber) = 0 ].<br>
        aNumber isNumber ifFalse: [ ^false ].<br>
        ^aNumber adaptToInteger: self andCompare: #=<br>
<br>
then the second number decreases to 18.0 with Cog. Changing this method has no effect on the interpreter VM&#39;s performance.<br>
<br>
Do you have an idea what can cause the slowdown and why does the implementation of Integer &gt;&gt; #= matter for Cog?<br>
<br>
Cheers,<br>
Levente<br></blockquote></blockquote></div></div></blockquote></div><br>-- <br>best,<div>Eliot</div><br>