<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 31, 2015 at 11:35 AM, Chris Muller <span dir="ltr">&lt;<a href="mailto:asqueaker@gmail.com" target="_blank">asqueaker@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
Sometimes the number of bytes is only known in a variable, so would it<br>
be possible to do 4 primitives which accept the number of bits (or<br>
bytes) as an argument?  (uint:at: uint:at:put:) * (big endian, little<br>
endian)<br></blockquote><div><br></div><div>Of course its possible, but such an architecture can hardly be quick.  If one needs the flexible primitives then use them, but don&#39;t hobble the system by only providing them.  Having a real 64-bit VM means that the use of 2 32-bit accesses is unnecessarily slow.</div><div><br></div><div>Which would you rather, and which would you think would be faster (I don&#39;t know, but I have my suspicions):</div><div><br></div><div>Expand the existing flexible integerAt: prims to integerAt:put:bytes:signed:bigEndian: (yuck), or implement this in terms of a wrapper something like<br></div><div><br></div><div>ByteArray&gt;&gt;integerAt: index bytes: numBytes signed: signed bigEndian: bigEndian</div><div><br></div><div>    ^size &gt;= 4</div><div>        ifTrue:</div><div>            [size = 8 ifTrue:</div><div>                [value := self unsignedLong64At: index.</div><div>                 bigEndian ifTrue:</div><div>                    [value := self byteReverseEightBytes: value].</div><div>                 (sign := value bitShift: -63) ~= 0 ifTrue: &quot;if the VM is intelligent about left shift of zero then this test is unnecessary...&quot;</div><div>                    [value := value - ((sign bitAnd: 1) bitShift: 64)].</div><div>                 ^value].</div><div>             size = 4 ifTrue:</div><div>                [value := self unsignedLong32At: index.</div><div>                 bigEndian ifTrue:</div><div>                    [value := self byteReverseFourBytes: value].</div><div>                 (sign := value bitShift: -31) ~= 0 ifTrue: &quot;if the VM is intelligent about left shift of zero then this test is unnecessary...&quot;</div><div>                    [value := value - ((sign bitAnd: 1) bitShift: 32)].</div><div>                 ^value].</div><div>             ^self error: &#39;size must be a power of two from 1 to 8&#39;]</div><div>        ifFalse:</div><div>...</div><div><br></div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class=""><div class="h5"><br>
<br>
On Mon, Aug 31, 2015 at 12:25 PM, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>
&gt; Hi Chrises,<br>
&gt;<br>
&gt;     my vote would be to write these as 12 numbered primitives, (2,4 &amp; 8<br>
&gt; bytes) * (at: &amp; at:put:) * (big &amp; little endian) because they can be<br>
&gt; performance critical and implementing them like this means the maximum<br>
&gt; efficiency in both 32-bit and 64-bit Spur, plus the possibility of the JIT<br>
&gt; implementing the primitives.<br>
&gt;<br>
&gt; On Sun, Aug 30, 2015 at 10:01 PM, Chris Cunningham &lt;<a href="mailto:cunningham.cb@gmail.com">cunningham.cb@gmail.com</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Hi Chris,<br>
&gt;&gt;<br>
&gt;&gt; I&#39;m all for having the fastest that in the image that works.  If you could<br>
&gt;&gt; make your version handle endianess, then I&#39;m all for including it (at least<br>
&gt;&gt; in the 3 variants that are faster).  My first use for this (interface for<br>
&gt;&gt; KAFKA) apparently requires bigEndianess, so I really want that supported.<br>
&gt;&gt;<br>
&gt;&gt; It might be best to keep my naming, though - it follows the name pattern<br>
&gt;&gt; that is already in the class.  Or will yours also support 128?<br>
&gt;&gt;<br>
&gt;&gt; -cbc<br>
&gt;&gt;<br>
&gt;&gt; On Sun, Aug 30, 2015 at 2:38 PM, Chris Muller &lt;<a href="mailto:asqueaker@gmail.com">asqueaker@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hi Chris, I think these methods belong in the image with the fastest<br>
&gt;&gt;&gt; implementation we can do.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; I implemented 64-bit unsigned access for Ma Serializer back in 2005.<br>
&gt;&gt;&gt; I modeled my implementation after Andreas&#39; original approach which<br>
&gt;&gt;&gt; tries to avoid LI arithmetic.  I was curious whether your<br>
&gt;&gt;&gt; implementations would be faster, because if they are then it could<br>
&gt;&gt;&gt; benefit Magma.  After loading &quot;Ma Serializer&quot; 1.5 (or head) into a<br>
&gt;&gt;&gt; trunk image, I used the following script to take comparison<br>
&gt;&gt;&gt; measurements:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; | smallN largeN maBa cbBa |  smallN := ((2 raisedTo: 13) to: (2<br>
&gt;&gt;&gt; raisedTo: 14)) atRandom.<br>
&gt;&gt;&gt; largeN := ((2 raisedTo: 63) to: (2 raisedTo: 64)) atRandom.<br>
&gt;&gt;&gt; maBa := ByteArray new: 8.<br>
&gt;&gt;&gt; cbBa := ByteArray new: 8.<br>
&gt;&gt;&gt; maBa maUint: 64 at: 0 put: largeN.<br>
&gt;&gt;&gt; cbBa unsignedLong64At: 1 put: largeN bigEndian: false.<br>
&gt;&gt;&gt; self assert: (cbBa maUnsigned64At: 1) = (maBa unsignedLong64At: 1<br>
&gt;&gt;&gt; bigEndian: false).<br>
&gt;&gt;&gt; { &#39;cbc smallN write&#39; -&gt; [ cbBa unsignedLong64At: 1 put: smallN<br>
&gt;&gt;&gt; bigEndian: false] bench.<br>
&gt;&gt;&gt; &#39;ma smallN write&#39; -&gt; [cbBa maUint: 64 at: 0 put: smallN ] bench.<br>
&gt;&gt;&gt; &#39;cbc smallN access&#39; -&gt; [ cbBa unsignedLong64At: 1 bigEndian: false. ]<br>
&gt;&gt;&gt; bench.<br>
&gt;&gt;&gt; &#39;ma smallN access&#39; -&gt; [ cbBa maUnsigned64At: 1] bench.<br>
&gt;&gt;&gt; &#39;cbc largeN write&#39; -&gt; [ cbBa unsignedLong64At: 1 put: largeN<br>
&gt;&gt;&gt; bigEndian: false] bench.<br>
&gt;&gt;&gt; &#39;ma largeN write&#39; -&gt; [cbBa maUint: 64 at: 0 put: largeN ] bench.<br>
&gt;&gt;&gt; &#39;cbc largeN access&#39; -&gt; [ cbBa unsignedLong64At: 1 bigEndian: false ]<br>
&gt;&gt;&gt; bench.<br>
&gt;&gt;&gt; &#39;ma largeN access&#39; -&gt; [ cbBa maUnsigned64At: 1] bench.<br>
&gt;&gt;&gt;  }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Here are the results:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; &#39;cbc smallN write&#39;-&gt;&#39;3,110,000 per second.  322 nanoseconds per run.&#39; .<br>
&gt;&gt;&gt; &#39;ma smallN write&#39;-&gt;&#39;4,770,000 per second.  210 nanoseconds per run.&#39; .<br>
&gt;&gt;&gt; &#39;cbc smallN access&#39;-&gt;&#39;4,300,000 per second.  233 nanoseconds per run.&#39; .<br>
&gt;&gt;&gt; &#39;ma smallN access&#39;-&gt;&#39;16,400,000 per second.  60.9 nanoseconds per run.&#39; .<br>
&gt;&gt;&gt; &#39;cbc largeN write&#39;-&gt;&#39;907,000 per second.  1.1 microseconds per run.&#39; .<br>
&gt;&gt;&gt; &#39;ma largeN write&#39;-&gt;&#39;6,620,000 per second.  151 nanoseconds per run.&#39; .<br>
&gt;&gt;&gt; &#39;cbc largeN access&#39;-&gt;&#39;1,900,000 per second.  527 nanoseconds per run.&#39; .<br>
&gt;&gt;&gt; &#39;ma largeN access&#39;-&gt;&#39;1,020,000 per second.  982 nanoseconds per run.&#39;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; It looks like your 64-bit access is 86% faster for accessing the<br>
&gt;&gt;&gt; high-end of the 64-bit range, but slower in the other 3 metrics.<br>
&gt;&gt;&gt; Noticeably, it was only 14% as fast for writing the high-end of the<br>
&gt;&gt;&gt; 64-bit range, and similarly as much slower for small-number access..<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Fri, Aug 28, 2015 at 6:01 PM, Chris Cunningham<br>
&gt;&gt;&gt; &lt;<a href="mailto:cunningham.cb@gmail.com">cunningham.cb@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt; Hi.<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt; I&#39;ve committed a change to the inbox with changes to allow<br>
&gt;&gt;&gt; &gt; getting/putting<br>
&gt;&gt;&gt; &gt; 64bit values to ByteArrays (similar to 32 and 16 bit accessors).  Could<br>
&gt;&gt;&gt; &gt; this<br>
&gt;&gt;&gt; &gt; be added to trunk?<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt; Also, first time I used the selective commit function - very nice!  the<br>
&gt;&gt;&gt; &gt; changes I didn&#39;t want committed didn&#39;t, in fact, get commited.  Just<br>
&gt;&gt;&gt; &gt; the<br>
&gt;&gt;&gt; &gt; desirable bits!<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt; -cbc<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; --<br>
&gt; _,,,^..^,,,_<br>
&gt; best, Eliot<br>
&gt;<br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>