About ~= and ~~

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Aliaksei Syrel
Hi

It is been a while...
So, do we want to replace ~~ with a primitive? :)

Cheers
Alex
Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Clément Béra
Hi

Do you mean you want to add this pragma "<primitive: 169>" in Object >> #~~ ?

Or do you mean replacing #blockCopy: by #~~ in the special selectors to get it inlined by default like #== ?


On Wed, Nov 23, 2016 at 2:39 PM, Aliaksei Syrel <[hidden email]> wrote:
Hi

It is been a while...
So, do we want to replace ~~ with a primitive? :)

Cheers
Alex



--
View this message in context: http://forum.world.st/About-and-tp3898409p4924391.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Clément Béra
In reply to this post by Aliaksei Syrel
Hi,

Support for primitive 169 for Object>>#~~ has been in the VM for a while. The default implementation in Squeak 5 uses this primitive for example.

I've just added today (VMMaker commit 2003) support for inlined #~~ like #== (including JIT support, branch pipelining, etc.). If one puts #~~ in the specialObjectsArray at the location of #blockCopy:, the bytecode compiler generates the special send bytecode for #~~ leading to improved performance and consistency between #== and #~~.

With today's update, the VM supports 3 inlined operations without any type checks: #==, #~~ and #class. It is possible to disable such optimisations in the bytecode compiler (In Pharo #class inlining is disabled there for example). Eliot would like to add support to disable these operations at VM level as a VM command line parameter too, and we may do it in the future.

Now this is for the VM support. It's up to the Pharo/Squeak/other community to decide what behavior they want in their runtime for these 3 selectors. 

In my opinion, I believe that #~~ should be consistent with #==, hence they should be both inlined or both sends to primitives. I don't like the current situation in Pharo nor in Squeak. 

Now when we look for solutions, we see that one of #== and #~~ needs to be a primitive (it's essential), hence it makes sense to have both Object>>#== and Object>>#~~ as primitives (with the primitive pragma in the method body). The inlining of #== and #~~ is arguable and I let the community decide what they believe is best for their runtime, though I would rather have the same behavior for both selectors.

Cheers

On Wed, Nov 23, 2016 at 2:39 PM, Aliaksei Syrel <[hidden email]> wrote:
Hi

It is been a while...
So, do we want to replace ~~ with a primitive? :)

Cheers
Alex



--
View this message in context: http://forum.world.st/About-and-tp3898409p4924391.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: [Vm-dev] About ~= and ~~

Eliot Miranda-2
Hi Clément, Hi All,

On Thu, Nov 24, 2016 at 5:09 AM, Clément Bera <[hidden email]> wrote:
 
Hi,

Support for primitive 169 for Object>>#~~ has been in the VM for a while. The default implementation in Squeak 5 uses this primitive for example.

I've just added today (VMMaker commit 2003) support for inlined #~~ like #== (including JIT support, branch pipelining, etc.). If one puts #~~ in the specialObjectsArray at the location of #blockCopy:, the bytecode compiler generates the special send bytecode for #~~ leading to improved performance and consistency between #== and #~~.

With today's update, the VM supports 3 inlined operations without any type checks: #==, #~~ and #class. It is possible to disable such optimisations in the bytecode compiler (In Pharo #class inlining is disabled there for example). Eliot would like to add support to disable these operations at VM level as a VM command line parameter too, and we may do it in the future.

Now this is for the VM support. It's up to the Pharo/Squeak/other community to decide what behavior they want in their runtime for these 3 selectors. 

In my opinion, I believe that #~~ should be consistent with #==, hence they should be both inlined or both sends to primitives. I don't like the current situation in Pharo nor in Squeak. 

Now when we look for solutions, we see that one of #== and #~~ needs to be a primitive (it's essential), hence it makes sense to have both Object>>#== and Object>>#~~ as primitives (with the primitive pragma in the method body). The inlining of #== and #~~ is arguable and I let the community decide what they believe is best for their runtime, though I would rather have the same behavior for both selectors.

In addition, for proxies, it makes sense to allow the system to not inline the primitives.  Let me explain.  The primitives for #== and #~~, just like any other primitives, are found by message sends.  However, a set of 32 "special" selectors, which comprise some arithmetic selectors (#+, #- etc) and comparison selectors (#< #<= etc) and some frequent selectors #(at: #next #value #== etc) are subject to inlining with no sends (see Smalltalk specialSelectoers for the full set).

The first sixteen are arithmetic and comparison, and the interpreter gains performance by implementing these byte codes to test for SmallIntegers and Floats, and performing the arithmetic directly without a send, and for the comparisons, performing the comparison and any immediately following conditional branch.  The JIT performs these optimisations too.  But these short-cuts (static type prediction in the official terminology) are safe because they apply only to SmallInteger and Float.

Of the next sixteen most are there only to save space in a method's literal frame.  Since the byte code encodes the selector directly there is no need to store the selector in the method's literals.  The implementation of all but two (three if we add #~~ to replace #blockCopy: as mentioned above) of these bytecodes is to fetch the selector from the specialSelectors array and do a normal send.

#== and #class are handled specially.  These are inlined without doing a send.  The current Opal compiler in Pharo avoids the inlining of #class by not generating the #class special selector bytecode.  Squeak's compiler still issues the special selector bytecode.  Both generate #== by issuing the #== special selector bytecode, and so #== is never sent.  This is not what's desired for applications that use proxies.  It is fine for simple applications that prefer speed.

One simple thing one can do is prevent inlining for anything other than the arithmetic and comparison operators.  A simple command-line switch, or perhaps better, a flag in the image header, can control whether the VM inlines #class, #== & #~~.  This then allows the compilers to generate the more compact special selector byte codes for these sends, but causes the VM to treat them like the other 13 non-arithmetic special selectors.  Hence they become true sends.  I did this for VisualWorks several years ago and it works well, expect for needing a command-line switch.  The flag in the image header is much more reliable; whether an image should be run with inlining or not is a property of the image, not of a particular VM invocation.

So I suggest that
a) I implement the switch as an image header flag, allowing the inlining of #class, #== and #~~ to be turned off (but keeping inlining on by default)
b) Pharo changes Opal to start issuing the #class special selector send byte code again and turns off inlining of #class, #== and #~~
c) applications that use proxies (in Cuis, Pharo or Squeak) experiment with the setting and see if logic is improved and report back; Squeak and other dialects can then decide what they want as the default, and indeed certain packages could try and set the flag or at least check that the flag is in the desired state 


Cheers

On Wed, Nov 23, 2016 at 2:39 PM, Aliaksei Syrel <[hidden email]> wrote:
Hi

It is been a while...
So, do we want to replace ~~ with a primitive? :)

Cheers
Alex



--
View this message in context: http://forum.world.st/About-and-tp3898409p4924391.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.






--
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Peter Uhnak
In reply to this post by Aliaksei Syrel
Out of interest... is the single extra dispatch really that expensive?

And speaking of object inequality... I would like to propose "<>" instead of "~=", because I never remember on which side ~ should be..

Peter

On Wed, Nov 23, 2016 at 05:39:03AM -0800, Aliaksei Syrel wrote:

> Hi
>
> It is been a while...
> So, do we want to replace ~~ with a primitive? :)
>
> Cheers
> Alex
>
>
>
> --
> View this message in context: http://forum.world.st/About-and-tp3898409p4924391.html
> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>

Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Uko2

> On 25 Nov 2016, at 19:31, Peter Uhnak <[hidden email]> wrote:
>
> Out of interest... is the single extra dispatch really that expensive?
>
> And speaking of object inequality... I would like to propose "<>" instead of "~=", because I never remember on which side ~ should be..

Let’s replace it with ~=~ then :P

Y

>
> Peter
>
> On Wed, Nov 23, 2016 at 05:39:03AM -0800, Aliaksei Syrel wrote:
>> Hi
>>
>> It is been a while...
>> So, do we want to replace ~~ with a primitive? :)
>>
>> Cheers
>> Alex
>>
>>
>>
>> --
>> View this message in context: http://forum.world.st/About-and-tp3898409p4924391.html
>> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: About ~= and ~~

Eliot Miranda-2
In reply to this post by Peter Uhnak
Hi Peter,

    I'd appreciate it if you used reply to all to keep the conversation thread going.

> On Nov 25, 2016, at 10:31 AM, Peter Uhnak <[hidden email]> wrote:
>
> Out of interest... is the single extra dispatch really that expensive?

Yes, in the common case where the send of #== is followed by a jump, as it is in ifNil:ifNotNil: or == foo ifTrue: etc.  when #== is inclined the following jump is eliminated and the VM jumps on the condition codes for the comparison.  When #== is a real send it answers the true or false objects and the following jump must compare this result against true or false.

Note that Sista will be able to perform the inclining optimisation so we will get the performance back once Sista is deployed.

>
> And speaking of object inequality... I would like to propose "<>" instead of "~=", because I never remember on which side ~ should be..
>
> Peter
>
>> On Wed, Nov 23, 2016 at 05:39:03AM -0800, Aliaksei Syrel wrote:
>> Hi
>>
>> It is been a while...
>> So, do we want to replace ~~ with a primitive? :)
>>
>> Cheers
>> Alex
>>
>>
>>
>> --
>> View this message in context: http://forum.world.st/About-and-tp3898409p4924391.html
>> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>>
>

12