[Pharo-dev] [Vm-dev] how slower is called a named primitive over
a numbered primitive?
David T. Lewis
lewis at mail.msen.com
Tue Jun 23 00:58:51 UTC 2015
On Mon, Jun 22, 2015 at 11:05:30AM -0700, Eliot Miranda wrote:
> On Mon, Jun 22, 2015 at 9:35 AM, David T. Lewis <lewis at mail.msen.com> wrote:
>
> >
> > That sounds right to me too. But it would be a worthwhile experiment to
> > set up a test to confirm it. Maybe take one or more methods that call
> > numbered primitives, and recode them to call the primitives by name. Then
> > measure and see if anything got slower.
> >
> > Dave
> >
>
> On Mon, Jun 22, 2015 at 10:40 AM, Eliot Miranda <eliot.miranda at gmail.com>
> wrote:
>
> > Hi Esteban,
> >
> > you can set up a test using the LargeInteger comparison primitives.
> > They're both named and numberd. e.g.
> >
> > 23 primitiveLessThanLargeIntegers
> >
> > So you can write e.g.
> >
> > LargePositiveInteger>>#< anInteger
> > "Primitive. Compare the receiver with the argument and answer true if
> > the receiver is less than the argument. Otherwise answer false. Fail if the
> > argument is not a SmallInteger or a LargePositiveInteger less than
> > 2-to-the-30th (1073741824).
> > Optional. See Object documentation whatIsAPrimitive."
> >
> > <primitive: 23>
> > ^super < anInteger
> >
> > as
> >
> > numberedLessThan: anInteger
> > "Primitive. Compare the receiver with the argument and answer true if
> > the receiver is less than the argument. Otherwise answer false. Fail if the
> > argument is not a SmallInteger or a LargePositiveInteger less than
> > 2-to-the-30th (1073741824).
> > Optional. See Object documentation whatIsAPrimitive."
> >
> > <primitive: 23>
> > ^super < anInteger
> >
> >
> > namedLessThan: anInteger
> > "Primitive. Compare the receiver with the argument and answer true if
> > the receiver is less than the argument. Otherwise answer false. Fail if the
> > argument is not a SmallInteger or a LargePositiveInteger less than
> > 2-to-the-30th (1073741824).
> > Optional. See Object documentation whatIsAPrimitive."
> >
> > <primitive: 'primitiveLessThanLargeIntegers'>
> > ^super < anInteger
> >
> > and test it with two suitable large integers. Will you report back? I'd
> > like to know the answer. Named primitive invocation should be slightly
> > slower. As Cl??ment says, a return different address is written to the
> > stack, overwriting the primitive code, but that return path is essentially
> > the same as for numbered primtiives. So I expect that there will be almost
> > no measurable difference.
> >
>
> Wow, it is indeed a significant difference. Substituting the return
> address must invoke all sorts of cost in an x86 cpu. Here are 2 x 5 runs
>
>
> | i | i := SmallInteger maxVal + 1.
> (1 to: 6) collect: [:j| {[1 to: 10000000 do: [:k| i numberedLessThan: i]]
> timeToRun. [1 to: 10000000 do: [:k| i namedLessThan: i]] timeToRun}]
>
> #(#(191 283) #(211 375) #(281 405) #(300 411) #(281 421) #(296 409))
> #(#(186 267) #(201 273) #(210 364) #(294 410) #(313 400) #(292 405))
>
> So the overhead is of the order of (100ms / 10,000,000) per call. e.g.
> around 10ns per named primitive call. Interesting :-)
On an interpreter VM, the results are as Tim and I initially expected:
| i | i := SmallInteger maxVal + 1.
(1 to: 6) collect: [:j| {[1 to: 10000000 do: [:k| i numberedLessThan: i]]
timeToRun. [1 to: 10000000 do: [:k| i namedLessThan: i]] timeToRun}]
==> #(#(791 789) #(793 794) #(793 790) #(791 791) #(790 794) #(795 789))
With a Cog VM, the numbered primitives are significantly faster:
| i | i := SmallInteger maxVal + 1.
(1 to: 6) collect: [:j| {[1 to: 10000000 do: [:k| i numberedLessThan: i]]
timeToRun. [1 to: 10000000 do: [:k| i namedLessThan: i]] timeToRun}]
==> #(#(542 670) #(542 668) #(544 678) #(546 680) #(540 666) #(540 680))
On Mon, Jun 22, 2015 at 07:16:43PM +0200, Cl??ment Bera wrote:
>
> Well it also depends if the primitive is generated by the JIT. If you
> rewrite SmallInteger>>#+ from primitive 1 to a named primitive the overhead
> will be more important than just the searching/loading/linking because the
> JIT won't compile it to n-code anymore.
So maybe this is the reason for the difference.
Note: this is with an old Cog VM, because I lost my primary PC and can't
restore it right now. But I think the results are relevant WRT this discussion.
/usr/local/lib/squeak/4.0-2776/squeak
Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.331]
Dave
More information about the Vm-dev
mailing list