[ 
https://issues.apache.org/jira/browse/RNG-72?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16780569#comment-16780569
 ] 

Alex D Herbert commented on RNG-72:
-----------------------------------

Hi Gilles,
{quote}I have also just noted that if you do want to seed using a fast 
SplitMix64 without synchronisation then the following is possible:

RandomSource.create(RandomSource.XOR_SHIFT_1024_S, Seedfactory.nextLong());
{quote}
This was an error. I meant:

"If you want to seed using a fast SplitMix64 without synchronisation *on every 
call to create a value for the array seed* then the following is possible:

RandomSource.create(RandomSource.XOR_SHIFT_1024_S, Seedfactory.nextLong());"

The call to {{Seedfactory.nextLong()}} will be synchronized. Then the input 
long is used to create a SplitMix64 which then fills the {{long[]}} seed 
without being synchronised. The results above show this. It is 6.5x slower to 
use a {{null}} seed via the factory method verses using a {{Long}} seed to 
create a XorShift1024Star which has a seed size of 16. However this is somewhat 
hindered by using a slower Well generator when the {{null}} seed is used which 
does not natively produce {{long}} values. So the actual effect of 
synchronising around the generator for each {{long}} is unknown unless the same 
generator is used.

This is because {{Long2LongArray}} uses a SplitMix internally. I had noted that 
{{Long2IntArray}} passes the SplitMix to the {{SeedFactory}} and so does not 
avoid synchronization, or the {{xor}} operation which it does with 0. I was 
going to change this.
{quote}How about keeping {{SeedFactory}}'s current set of methods untouched, 
but add a "fast" alternative whenever it would be significantly faster than the 
synchronized version (and the caller does not care that the seed would not be 
as diverse)
{quote}
This would be a good addition. Effectively move the code from 
{{Long2LongArray}} to the {{SeedFactory}} and update the code used by 
{{Long2IntArray}} in the {{SeedFactory}}.
  

I still think that the SeedFactory would benefit from using a faster generator. 
The period of XorShift1024Star should be enough to create a lot of seed values 
but it is much faster than Well44497b.

However the current benchmark shows that there is a lot to improve in the 
construction time of generators without touching the SeedFactory. My plan is to:
 * Optimise the construction, allowing removal of reflection to create the 
generators and add knowledge of array seed length
 * Optimise constructors for each generator where possible
 * Optimise the {{Long}} to array seed converters to use the {{SeedFactory}} 
possibly exposing new faster *public* seed generation methods
 * Benchmark again with changes to the SeedFactory (changing the underlying 
generator with/without using the random hashcode)

 

> Create a RandomSource.create benchmark
> --------------------------------------
>
>                 Key: RNG-72
>                 URL: https://issues.apache.org/jira/browse/RNG-72
>             Project: Commons RNG
>          Issue Type: New Feature
>          Components: simple
>    Affects Versions: 1.3
>            Reporter: Alex D Herbert
>            Assignee: Alex D Herbert
>            Priority: Minor
>              Labels: performance-benchmark
>             Fix For: 1.3
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> The recommended method to construct a {{UniformRandomProvider}} is to use, 
> e.g.:
> {code:java}
> import org.apache.commons.rng.UniformRandomProvider;
> import org.apache.commons.rng.simple.RandomSource;
> UniformRandomProvider rng = RandomSource.create(RandomSource.MWC_256);
> {code}
> The factory method knows the type of seed required for the constructor and 
> generates one as appropriate.
> This factory method could be made more efficient, in particular:
>  * Reducing synchronisation around the single source of random seed data
>  * Adding knowledge of the required seed size for arrays
>  * Changing internal data structures, e.g. {{Map<Class<?>, 
> SeedConverter<?,?>>}} can be changed to {{Map<SeedType, SeedConverter<?,?>>}} 
> using an {{EnumMap}} if a new enum {{SeedType}} was created for all the 
> supported seeds (currently 4 types).
>  * Add a new interface to replace {{SeedConverter<?,?>.convert()}} with a 
> {{.convert(int outputArraySize)}} method to allow conversions to generate 
> appropriately sized arrays. The parameter can be ignored for non-array 
> conversions but could optimise array conversions.
> This ticket is to add a JMH benchmark to compare the speed of construction of 
> all the providers using:
>  * Their native constructor
>  * {{RandomSource}} using the native seed of the correct size (calls a 
> constructor using reflection)
>  * {{RandomSource}} using a non native seed (requires seed conversion)
>  * {{RandomSource}} using no seed (requires seed generation)
> The report will be posted here. It could be added to the user guide for 
> reference.
> This work is motivated by the new {{XorShiRo}} generators in version 1.3 that 
> have a native array seed size of 2, 4, or 8. The current {{RandomSource}} 
> create method will generate a fixed seed of length 128 for seeding.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to