pharo-vm
pharo-vm copied to clipboard
Added a random number primitive
Added primitiveRandom which generates a random 31 bits integer basing on a 64 bits state.
Based on Permuted Congruential Generators (https://www.pcg-random.org/index.html)
Why do we need an arbitrary pseudo random generator in the VM? It can be done in the image. If it's for performance, it could be done in a plugin.
Why do we need an arbitrary pseudo random generator in the VM? It can be done in the image. If it's for performance, it could be done in a plugin.
The goal was to have a fast way to generate pseudo-random number while we were replacing the default Pharo generator, which is quite bad
Hi @BastouP411 I imagine this PR is now obsolete, replaced by a full Pharo version of the code. I'll close this PR, please feel free to reopen it if I was mistaken
Okay I did not see this was closed. So, pharo-project/pharo#14230 was integrated with support for this primitive, so I did some measurmements.
r := Random new.
r seed: 42.
[ r privateNextValue ] bench.
"With primitive: 450,129,783 iterations in 5 seconds 2 milliseconds. 89989960.616 per second"
"Without primitive: 7,317,172 iterations in 5 seconds 3 milliseconds. 1462556.866 per second"
89989960.616/1462556.866. "Primitive version is 61.5 times faster !"
The version that uses the primitive is 61.5 times faster so there is a benefit when generating lots of random numbers. What we need to discuss is also how we implement the primitive, do we do it with a plugin, like @privat proposed ? or do we leave it as a primitive ? If we put it in a plugin, do we create a plugin with a single function inside, or do we use an existing one ?
I profiled the code a bit in latest Pharo12. The Pharo code is generating lots of large integers. It would be interesting to see how to reimplement it without
The biggest problems I see are
6364136223846793005and1442695040888963407are larger than 60 bits (small integer max representation)returnValue << (count negated bitAnd: 31)shifts left by at most 32, which means that the numbers of more than 30 bits will overflow and create a large integer
I profiled the code a bit in latest Pharo12. The Pharo code is generating lots of large integers. It would be interesting to see how to reimplement it without
How could we reimplement without these large integers ? cutting the multiplication and using multiple bitAnd ?
I profiled the code a bit in latest Pharo12. The Pharo code is generating lots of large integers. It would be interesting to see how to reimplement it without
How could we reimplement without these large integers ? cutting the multiplication and using multiple bitAnd ?
That would be fun to try. Check the implementation of ThirtyTwoBitRegister, maybe we could have try having an implementation of SixtyFourBitRegister? Of course, these could be improved by having a primitive implementation, but in that case, it would have other usages too :)
For an initial implementation of 64-bit register implementation you may check this PR https://github.com/pharo-project/pharo/pull/14616
I'll close this PR for now, primitive 231 has been taken in the meantime. I kind of agree with @privat here on the fact that maybe a simple C library with an FFI function is enough!