On Mon, 15 Mar 2021 20:45:30 GMT, Paul Sandoz <psan...@openjdk.org> wrote:

>> I still don't like the fact that the factory uses reflection but i don't see 
>> how to do better
>
> This is now looking very nicely structured.
> 
> The only thing i am unsure are the details around `RandomGenerator` being a 
> service provider interface. The documentation mentions this at various points 
> (mostly as implementation notes), but it's not really called out on 
> `RandomGenerator`. 
> 
> Trying out the patch, I can implement `RandomGenerator` and register it as a 
> service:
> 
> public class AlwaysZero implements RandomGenerator {
>     @Override
>     public long nextLong() {
>         return 0;
>     }
> }
> ...
>         RandomGenerator alwaysZero = RandomGenerator.of("AlwaysZero");
>  
> 
> Is that intended? (esp. since the annotation `RandomGeneratorProperties` is 
> not public). If i rename the above to `L32X64MixRandom` an 
> `ExceptionInInitializerError` is produced due to duplicate keys.
> 
> I suspect you want to filter out the service providers to those that only 
> declare `RandomGeneratorProperties`, thereby restricting to providers only 
> supplied by the platform.

Has anyone here benchmarked this? I've run BumbleBench benchmarks (one of the 
AdoptOpenJDK team's tools, [available 
here](https://github.com/adoptium/bumblebench)) and I'm skeptical of the 
original claims in [JEP 356](https://openjdk.java.net/jeps/356), namely:

> ...a new class of splittable PRNG algorithms (LXM) has also been discovered 
> that are almost as fast [as SplittableRandom]...

On my machine, L64X128MixRandom's algorithm is 53% slower than 
SplittableRandom, a halving in performance that I think would be inaccurate to 
describe as "almost as fast." I've benchmarked on Java 8 HotSpot (Windows 10, 
x64) and Java 15 OpenJ9 (same machine). On HotSpot, which I think is the main 
concern, I go from 1021770880 (over 1 billion) random longs per second with 
SplittableRandom to 479769280 (over 479 million) with my (I believe faithful) 
implementation of L64X128MixRandom. That is where I observed the 53% reduction. 
While SplittableRandom specifically seems to perform relatively badly on 
OpenJ9, with 893283072 longs per second (893 million), other similar random 
number generators do extremely well on OpenJ9; 
[LaserRandom](https://github.com/tommyettinger/jdkgdxds/blob/master/src/main/java/com/github/tommyettinger/ds/support/LaserRandom.java)
 generates 4232752128 random longs per second (4.2 billion) where 
L64X128MixRandom gets 840015872 (840 million). My benchmark repo is a
  mess, but if anyone wants to see and verify, [here it 
is](https://github.com/tommyettinger/assorted-benchmarks/tree/master/src/main/java/net/adoptopenjdk/bumblebench/examples).
 JMH benchmarks might provide different or just additional useful information; 
I've only run BumbleBench.

One could make the argument that getting a random long from a PRNG takes so 
little time in the first place that it is unlikely to be a bottleneck, and by 
that logic, LXM is "almost as fast." However, if random generation is not being 
called often enough for its speed to matter, you are exceedingly unlikely to 
need so many (over 9 quintillion) parallel streams or such a long period per 
stream ((2 to the 192) minus (2 to the 64)). LXM is also 1-dimensionally 
equidistributed, while the foundation it is built on should allow 4-dimensional 
equidistribution (with the caveat of any LFSR that an all-zero state is 
impossible), with the same memory use per generator (4 longs), a longer period, 
and comparable quality using `xoshiro256**`, or possibly `xoshiro256++`, giving 
up streams but permitting twice as many leaps as LXM has streams if you 
maintain the same period as L64X128MixRandom.

If I were implementing a PRNG to operate in a future official version of the 
JVM, I would definitely look into ways to use AES-NI, and I think the 
interfaces provided here should be valuable for any similar addition, even if I 
disagree with the provided implementations of those interfaces. Thank you for 
your time.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

Reply via email to