<div dir="ltr">Hi Levente, <div><br></div><div>VMMaker.oscog-cb.2323 tries to solve the slow-down problem you mentioned here by decreasing the number of instructions in the copying loops from 7 to 5. <br></div><div><br></div><div>On my machine, it seems at 10k elements, copying time improved by a factor of 1.25.</div><div><br></div>Copying loop becomes (replReg is adjusted by a diff ahead of the loop)<div><br></div><div>(pointer):<br><font face="monospace, monospace">instr := cogit MoveXwr: startReg R: replReg R: TempReg.<br>cogit MoveR: TempReg Xwr: startReg R: arrayReg.<br>cogit AddCq: 1 R: startReg.<br>cogit CmpR: startReg R: stopReg.<br>cogit JumpAboveOrEqual: instr.</font><br><br>(bytes):<br><font face="monospace, monospace">instr := cogit MoveXbr: startReg R: replReg R: TempReg.<br>cogit MoveR: TempReg Xbr: startReg R: arrayReg.<br>cogit AddCq: 1 R: startReg.<br>cogit CmpR: startReg R: stopReg.<br>cogit JumpAboveOrEqual: instr.</font><div><font face="monospace, monospace"><br></font></div><div><font face="arial, helvetica, sans-serif">Since replReg unlike arrayReg is unused afterwards, we could cheat more to free one register using replReg as the counter use the fixed index read instr with index 0, but I am too lazy to do it. </font><span style="font-family:arial,helvetica,sans-serif">I wanted to do this since incrementing 2 counters felt a bit cumbersome and I wanted to try out the tight loop scheme they use in V8. That's what mostly pays off (removing an unconditional jump).</span></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">I guess there is still some slow down when copying large byte object - if some-one could compute the threshold at which point the C code is faster and what is the performance difference factor, tell me, I may change the jitted code so it falls back to the C primitive over this </font><span style="font-family:arial,helvetica,sans-serif">threshold.</span></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Hopefully next month we'll discuss the #compareTo:[collated:] primitive for data objects (in [ ] optional parameters, default being ASCII order)... Much to discuss since we can use pointer comparison for byte objects, even for the last word since unused bytes are zeroed, of course if we deal with some narrow cases...</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div></div><div><font face="arial, helvetica, sans-serif">Best,</font></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 25, 2017 at 10:57 PM, Levente Uzonyi <span dir="ltr"><<a href="mailto:leves@caesar.elte.hu" target="_blank">leves@caesar.elte.hu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Clémont,<br>
<br>
I finally found the time to write some benchmarks.<br>
I compared the output of the script below on sqcogspur64linuxht vm 201710061559 and 201712221331 avaiable on bintray.<br>
<br>
result := { ByteArray. DoubleByteArray. WordArray. DoubleWordArray. ByteString. WideString. FloatArray. Array } collect: [ :class |<br>
        | collection |<br>
        Smalltalk garbageCollect.<br>
        collection := class basicNew: 10000.<br>
        class -> (#(0 1 2 5 10 20 50 100 200 500 1000 2000 5000 10000) collect: [ :size |<br>
                | iterations time overhead |<br>
                iterations := (40000000 // (size max: 1) sqrt) floor.<br>
                overhead := [ 1 to: iterations do: [ :i | ] ] timeToRun.<br>
                time := [ 1 to: iterations do: [ :i |<br>
                        collection replaceFrom: 1 to: size with: collection startingAt: 1 ] ] timeToRun.<br>
                { size. iterations. time - overhead } ]) ].<br>
<br>
I found that the quick paths are probably only implented for bytes and pointers collections, because there was no significant difference for DoubleByteArray, WordArray, DoubleWordArray, WideString and FloatArray.<br>
<br>
For pointers and bytes collections, there's significant speedup when the copied portion is small. However, somewhere between 50 and 100 copied elements, the copying of bytes collections becomes slower (up to 1.5x @ 100k elements) with the newer VM.<br>
It's interesting that this doesn't happen to pointers classes. Instead of slowdown there's still 1.5x speedup even at 100k elements.<br>
<br>
Levente<div><div class="h5"><br>
<br>
On Mon, 23 Oct 2017, Clément Bera wrote:<br>
<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
Hi all,<br>
For a long time I was willing to add primitive #replaceFrom:to:with:startingA<wbr>t: in the JIT but did not take time to do it. These days I am showing the JIT to one of my students and as an example of how one would write code in the JIT we implemented this primitive<br>
together, Spur-only. This is part of commit 2273.<br>
<br>
I implemented quick paths for byte objects and array-like objects only. The rationale behind this is that the most common cases I see in Pharo user benchmarks in the profiler is copy of arrays and byteStrings. Typically some application benchmarks would show 3-5% of<br>
time spent in copying small things, and switching from the JIT runtime to C runtime is an important part of the cost.<br>
<br>
First evaluation shows the following speed-ups, but I've just done that quickly in my machine:<br>
<br>
Copy of size 0<br>
    Array 2.85x<br>
    ByteString 2.7x<br>
Copy of size 1<br>
    Array 2.1x<br>
    ByteString 2x<br>
Copy of size 3<br>
    Array 2x<br>
    ByteString 1.9x<br>
Copy of size 8<br>
    Array 1.8x<br>
    ByteString 1.8x<br>
Copy of size 64<br>
   Array 1.1x<br>
   ByteString 1.1x<br>
Copy of size 1000<br>
   Array 1x<br>
   ByteString 1x<br>
<br>
So I would expect some macro benchmarks to get 1 to 3% percent speed-up. Not as much as I expected but it's there.<br>
<br>
Can someone who is good at benchmarks such as Levente have a look and provide us with a better evaluation of the performance difference ?<br>
<br>
Thanks.<br>
<br>
--<br></div></div>
Clément BéraPharo consortium engineer<span class=""><br>
<a href="https://clementbera.wordpress.com/" rel="noreferrer" target="_blank">https://clementbera.wordpress.<wbr>com/</a><br>
Bâtiment B 40, avenue Halley 59650 Villeneuve d'Ascq<br>
<br>
</span></blockquote>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><span style="font-size:12.8px">Clément Béra</span><div style="font-size:12.8px">Pharo consortium engineer</div><div style="font-size:12.8px"><a href="https://clementbera.wordpress.com/" target="_blank">https://clementbera.wordpress.com/</a><br></div><div style="font-size:12.8px"><span style="line-height:16px">Bâtiment B 40, avenue Halley 59650 </span><span style="font-weight:bold;line-height:16px">Villeneuve d'Ascq</span></div></div></div>
</div>