pharo-vm icon indicating copy to clipboard operation
pharo-vm copied to clipboard

Added a random number primitive

Open Mathilde411 opened this issue 2 years ago • 9 comments

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)

Mathilde411 avatar Jul 06 '23 12:07 Mathilde411

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.

privat avatar Jul 06 '23 13:07 privat

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

Mathilde411 avatar Jul 06 '23 13:07 Mathilde411

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

guillep avatar Jul 18 '23 20:07 guillep

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 ?

Mathilde411 avatar Jul 27 '23 09:07 Mathilde411

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

guillep avatar Jul 28 '23 23:07 guillep

The biggest problems I see are

  • 6364136223846793005 and 1442695040888963407 are 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

guillep avatar Jul 28 '23 23:07 guillep

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 ?

Mathilde411 avatar Aug 03 '23 11:08 Mathilde411

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 :)

guillep avatar Aug 04 '23 10:08 guillep

For an initial implementation of 64-bit register implementation you may check this PR https://github.com/pharo-project/pharo/pull/14616

hernanmd avatar Sep 07 '23 18:09 hernanmd

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!

guillep avatar Jun 28 '24 07:06 guillep