On Sat, Sep 01, 2012 at 04:44:21PM +0200, Levente Uzonyi wrote:
On Sat, 1 Sep 2012, David T. Lewis wrote:
I have integrated these fixes into trunk VMMaker for testing. The new #testMinimumNegativeIntegerArithmetic unit test passes, and a VM compiled in 64-bit mode no longer crashed. I can find no significant change in performance with these changes applied. This looks really good to me, and if there are no other comments or issues I will go ahead and post the update to trunk VMMaker.
That sounds great, thanks Dave.
Here are the performance measurements that I did to compare VM performance before and after applying the changes. This is done with an interpreter VM compiled in 64 bit mode on Linux:
testBlock := [(1 to: 1000000) do: [:e | | largeNegativeInt | largeNegativeInt := -9223372036854775808 + e. largeNegativeInt >> 3. largeNegativeInt + 1. largeNegativeInt - -1. largeNegativeInt // -1. largeNegativeInt \ -1. largeNegativeInt rem: -1. largeNegativeInt quo: -1. largeNegativeInt * -1. largeNegativeInt / -1]].
What's the reason for using #to: and #do: instead of #to:do:?
Ignorance on my part.
The latter seems to be much more appropriate in such tests, because it doesn't create any objects and message sends, so garbage collection has less effect on the measurements.
Repeating the measurements using #to:do: below. After applying Nicolas' fixes, there does appear to be a slight improvement in large integer performance as measured by the testBlock, and a slight decrease in bytecodes/sec.
I cannot explain either of these performance variations. I don't see any reason that the changes to the primitives should affect bytecode performance, but I'm attaching a diff of the generated interp.c files before and after the changes in case anyone wants to have a look.
Test results are:
testBlock := [1 to: 1000000 do: [:e | | largeNegativeInt | largeNegativeInt := -9223372036854775808 + e. largeNegativeInt >> 3. largeNegativeInt + 1. largeNegativeInt - -1. largeNegativeInt // -1. largeNegativeInt \ -1. largeNegativeInt rem: -1. largeNegativeInt quo: -1. largeNegativeInt * -1. largeNegativeInt / -1]].
Before Nicolas' changes:
(LargeNegativeIntegerTest selector: #testMinimumNegativeIntegerArithmetic) run ==> 1 run, 0 passes, 0 expected failures, 1 failures, 0 errors, 0 unexpected passes
Time millisecondsToRun: testBlock ==> 4597 Time millisecondsToRun: testBlock ==> 4592 Time millisecondsToRun: testBlock ==> 4602 Time millisecondsToRun: testBlock ==> 4605 Time millisecondsToRun: testBlock ==> 4627
0 tinyBenchmarks ==> '424192212 bytecodes/sec; 14451784 sends/sec' 0 tinyBenchmarks ==> '424543946 bytecodes/sec; 15114601 sends/sec' 0 tinyBenchmarks ==> '421746293 bytecodes/sec; 14451784 sends/sec' 0 tinyBenchmarks ==> '423490488 bytecodes/sec; 15114601 sends/sec' 0 tinyBenchmarks ==> '423490488 bytecodes/sec; 14463110 sends/sec'
After, with fixes:
(LargeNegativeIntegerTest selector: #testMinimumNegativeIntegerArithmetic) run ==> 1 run, 1 passes, 0 expected failures, 0 failures, 0 errors, 0 unexpected passes
Time millisecondsToRun: testBlock ==> 4416 Time millisecondsToRun: testBlock ==> 4432 Time millisecondsToRun: testBlock ==> 4410 Time millisecondsToRun: testBlock ==> 4400 Time millisecondsToRun: testBlock ==> 4440
0 tinyBenchmarks ==> '438731790 bytecodes/sec; 15028443 sends/sec' 0 tinyBenchmarks ==> '442906574 bytecodes/sec; 14775763 sends/sec' 0 tinyBenchmarks ==> '440619621 bytecodes/sec; 14752141 sends/sec' 0 tinyBenchmarks ==> '436115843 bytecodes/sec; 14775763 sends/sec' 0 tinyBenchmarks ==> '442141623 bytecodes/sec; 14763943 sends/sec'
Dave