Re: [Pharo-project] Remove #class as a Compiler optimization
On Mar 25, 2011, at 5:26 PM, Mariano Martinez Peck wrote:
Hi. I have to say that I hate that the compiler associates a special bytecode for #class and that the VM don't even send the message. I want to be able to overwrite #class in a proxy for example, or to debug it.
I did some benchmarks disabling such optimization by doing:
(ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: []. Compiler recompileAll.
And the difference is NOTHING in my tests (maybe I am doing something wrong).
With Standard VM and #class optimization
[SystemNavigation default allObjectsDo: [:each | each class]] timeToRun -> aprox 50 miliseconds
What is the constant over head of doing just the iteration? [SystemNavigation default allObjectsDo: [:each | ]] timeToRun
What do you think?
I am for... for the JIT is is a monomorphic send to a primitive, so the IC will be very effective and should take care that the lookup is actually almost never done. (and the lookup is the only thing the #class bytecode saves, as the target method is a primitive). Marcus -- Marcus Denker -- http://www.marcusdenker.de INRIA Lille -- Nord Europe. Team RMoD.
What do you think?
I am for... for the JIT is is a monomorphic send to a primitive, so the IC will be very effective and should take care that the lookup is actually almost never done. (and the lookup is the only thing the #class bytecode saves, as the target method is a primitive). I think that programmers should have the illusion that the VM interacts with the system through message sends. By being able to overwrite this particular message you break this illusion. The VM will just fetch the real class; but the user doesn't get access to it anymore. Telling the system that this particular message shouldn't be overwritten is probably a good thing.
If you want to overwrite the method class, maybe your tools should send another message than class in the first place? I do however agree that many other optimizations become slightly superfluous, such as bytecodes for integer operations ... that somehow seems like compile-time inline-cached behavior without the ability to flush the cache :) cheers, Toon
On Fri, Mar 25, 2011 at 7:08 PM, Toon Verwaest <toon.verwaest@gmail.com>wrote:
What do you think?
I am for... for the JIT is is a monomorphic send to a primitive, so the IC will be very effective and should take care that the lookup is actually almost never done. (and the lookup is the only thing the #class bytecode saves, as the target method is a primitive).
I think that programmers should have the illusion that the VM interacts with the system through message sends. By being able to overwrite this particular message you break this illusion. The VM will just fetch the real class; but the user doesn't get access to it anymore. Telling the system that this particular message shouldn't be overwritten is probably a good thing.
If you want to overwrite the method class, maybe your tools should send another message than class in the first place?
Of course I can do that. I can also do (ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: []. Compiler recompileAll. I don't care. I have it working for my "usage". This was just an example. And don't compare #class with all the boolean methods like #ifNil: and friends or the bytecodes for integer operations....I think #class is sent far less times than those...
I do however agree that many other optimizations become slightly superfluous, such as bytecodes for integer operations ... that somehow seems like compile-time inline-cached behavior without the ability to flush the cache :)
cheers, Toon
On 25 March 2011 19:22, Mariano Martinez Peck <marianopeck@gmail.com> wrote:
On Fri, Mar 25, 2011 at 7:08 PM, Toon Verwaest <toon.verwaest@gmail.com> wrote:
What do you think?
I am for... for the JIT is is a monomorphic send to a primitive, so the IC will be very effective and should take care that the lookup is actually almost never done. (and the lookup is the only thing the #class bytecode saves, as the target method is a primitive).
I think that programmers should have the illusion that the VM interacts with the system through message sends. By being able to overwrite this particular message you break this illusion. The VM will just fetch the real class; but the user doesn't get access to it anymore. Telling the system that this particular message shouldn't be overwritten is probably a good thing.
If you want to overwrite the method class, maybe your tools should send another message than class in the first place?
Of course I can do that. I can also do
   (ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: [].    Compiler recompileAll.
I don't care. I have it working for my "usage". This was just an example.
And don't compare #class with all the boolean methods like #ifNil: and friends or the bytecodes for integer operations....I think #class is sent far less times than those...
Yes. and i predict that performance impact in macro benchmarks, where you running normal code (which not sending this message intentionally in a loop) will be at the noise level magnitude.
I do however agree that many other optimizations become slightly superfluous, such as bytecodes for integer operations ... that somehow seems like compile-time inline-cached behavior without the ability to flush the cache :)
cheers, Toon
-- Best regards, Igor Stasenko AKA sig.
On Fri, Mar 25, 2011 at 8:27 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 25 March 2011 19:22, Mariano Martinez Peck <marianopeck@gmail.com> wrote:
On Fri, Mar 25, 2011 at 7:08 PM, Toon Verwaest <toon.verwaest@gmail.com> wrote:
What do you think?
I am for... for the JIT is is a monomorphic send to a primitive, so the IC will be very effective and should take care that the lookup is actually almost never done.
(and
the lookup is the only thing the #class bytecode saves, as the target method is a primitive).
I think that programmers should have the illusion that the VM interacts with the system through message sends. By being able to overwrite this particular message you break this illusion. The VM will just fetch the real class; but the user doesn't get access to it anymore. Telling the system that this particular message shouldn't be overwritten is probably a good thing.
If you want to overwrite the method class, maybe your tools should send another message than class in the first place?
Of course I can do that. I can also do
(ParseNode classVarNamed: 'StdSelectors') removeKey: #class ifAbsent: []. Compiler recompileAll.
I don't care. I have it working for my "usage". This was just an example.
And don't compare #class with all the boolean methods like #ifNil: and friends or the bytecodes for integer operations....I think #class is sent far less times than those...
Yes. and i predict that performance impact in macro benchmarks, where you running normal code (which not sending this message intentionally in a loop) will be at the noise level magnitude.
So...what about doing something more real...for example, run all the testcases and compare time. Wouldn't that be a good "benchmark" ? BTW, can I run all test from code? (not using the TestRunner UI)
I do however agree that many other optimizations become slightly superfluous, such as bytecodes for integer operations ... that somehow
seems
like compile-time inline-cached behavior without the ability to flush the cache :)
cheers, Toon
-- Best regards, Igor Stasenko AKA sig.
I don't care. I have it working for my "usage". This was just an example.
And don't compare #class with all the boolean methods like #ifNil: and friends or the bytecodes for integer operations....I think #class is sent far less times than those...
Yes. and i predict that performance impact in macro benchmarks, where you running normal code (which not sending this message intentionally in a loop) will be at the noise level magnitude.
So...what about doing something more real...for example, run all the testcases and compare time. Wouldn't that be a good "benchmark" ?
sounds already better. make sure to run it something like 100 times, get the average and the standard deviation. otherwise the results don't provide much information.
BTW, can I run all test from code? (not using the TestRunner UI)
something like the following code should do it. TestCase allSubclasses do: [ :cls| cls isAbstract ifFalse: [cls run]].
So....I tried with running all tests of a PharoCore 1.3 and I've got this: cog vm with optimization Time to run all tests:116506 cog vm without optimization Time to run all tests:121930 121930 - 116506 ----> 5424 ((5424 * 100) / 116506) asFloat ---> 4.655554220383499 So...in Cog, running all test, there is an overhead of 4.6% Do we want to pay it ? I would...but I am all ears. Cheers Mariano On Mon, Mar 28, 2011 at 11:08 AM, Camillo Bruni <camillo.bruni@inria.fr>wrote:
I don't care. I have it working for my "usage". This was just an example.
And don't compare #class with all the boolean methods like #ifNil: and friends or the bytecodes for integer operations....I think #class is sent far less times than those...
Yes. and i predict that performance impact in macro benchmarks, where you running normal code (which not sending this message intentionally in a loop) will be at the noise level magnitude.
So...what about doing something more real...for example, run all the testcases and compare time. Wouldn't that be a good "benchmark" ?
sounds already better. make sure to run it something like 100 times, get the average and the standard deviation. otherwise the results don't provide much information.
BTW, can I run all test from code? (not using the TestRunner UI)
something like the following code should do it.
TestCase allSubclasses do: [ :cls| cls isAbstract ifFalse: [cls run]].
-- Mariano http://marianopeck.wordpress.com
On 5 April 2011 11:33, Mariano Martinez Peck <marianopeck@gmail.com> wrote:
So....I tried with running all tests of a PharoCore 1.3 and I've got this:
cog vm with optimization Time to run all tests:116506
cog vm without optimization Time to run all tests:121930
121930 - 116506 ----> 5424 ((5424 * 100) / 116506) asFloat ---> 4.655554220383499
So...in Cog, running all test, there is an overhead of 4.6%
Do we want to pay it ?
I would...but I am all ears.
5% for #class message? this is too much. or you also removed other optimized sends?
Cheers
Mariano
On Mon, Mar 28, 2011 at 11:08 AM, Camillo Bruni <camillo.bruni@inria.fr> wrote:
I don't care. I have it working for my "usage". This was just an example.
And don't compare #class with all the boolean methods like #ifNil:  and friends  or the bytecodes for integer operations....I think #class is sent far less times than those...
Yes. and i predict that performance impact in macro benchmarks, where you running normal code (which not sending this message intentionally in a loop) will be at the noise level magnitude.
So...what about doing something more real...for example, run all the testcases and compare time. Wouldn't that be a good "benchmark" ?
sounds already better. make sure to run it something like 100 times, get the average and the standard deviation. otherwise the results don't provide much information.
BTW, can I run all test from code? (not using the TestRunner UI)
something like the following code should do it.
TestCase allSubclasses do: [ :cls|     cls isAbstract         ifFalse: [cls run]].
-- Mariano http://marianopeck.wordpress.com
-- Best regards, Igor Stasenko AKA sig.
On Tue, Apr 5, 2011 at 12:09 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 5 April 2011 11:33, Mariano Martinez Peck <marianopeck@gmail.com> wrote:
So....I tried with running all tests of a PharoCore 1.3 and I've got this:
cog vm with optimization Time to run all tests:116506
cog vm without optimization Time to run all tests:121930
121930 - 116506 ----> 5424 ((5424 * 100) / 116506) asFloat ---> 4.655554220383499
So...in Cog, running all test, there is an overhead of 4.6%
Do we want to pay it ?
I would...but I am all ears.
5% for #class message? this is too much. or you also removed other optimized sends?
Only that one. For #== I got 4.3. And doing both together (#class and #==) I got 9.05% :( And removing the #class optimization in a Interpreter VM gives me almost as in cog: 4.7% maybe I am doing something wrong...
Cheers
Mariano
On Mon, Mar 28, 2011 at 11:08 AM, Camillo Bruni <camillo.bruni@inria.fr> wrote:
I don't care. I have it working for my "usage". This was just an example.
And don't compare #class with all the boolean methods like #ifNil: and friends or the bytecodes for integer operations....I think #class
is
sent
far less times than those...
Yes. and i predict that performance impact in macro benchmarks, where you running normal code (which not sending this message intentionally in a loop) will be at the noise level magnitude.
So...what about doing something more real...for example, run all the testcases and compare time. Wouldn't that be a good "benchmark" ?
sounds already better. make sure to run it something like 100 times, get the average and the standard deviation. otherwise the results don't provide much information.
BTW, can I run all test from code? (not using the TestRunner UI)
something like the following code should do it.
TestCase allSubclasses do: [ :cls| cls isAbstract ifFalse: [cls run]].
-- Mariano http://marianopeck.wordpress.com
-- Best regards, Igor Stasenko AKA sig.
-- Mariano http://marianopeck.wordpress.com
participants (5)
-
Camillo Bruni -
Igor Stasenko -
Marcus Denker -
Mariano Martinez Peck -
Toon Verwaest