commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Alex D Herbert (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (RNG-78) ThreadLocalRandomSource
Date Sun, 03 Mar 2019 21:21:00 GMT

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

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

I have created an initial implementation.

The factory method does not accept arguments for the {{RandomSource}}. This is because the
first call to create the random generator will fix the arguments. Subsequent calls with different
arguments cannot be supported as only one generator is stored per enum value. So the simplest
solution is to not support this for generators that have arguments. This is current only {{TWO_CMRES_SELECT}}.

I added a benchmark that simulates a worst case scenario for short lifetime generators. It
uses JMH to run threads in parallel to create a generator and then produce numbers. I have
some results for an easy to construct SPLIT_MIX and a harder to construct MWC_256. The generators
were used to create {{long}} values.

For reference I have compared to {{ThreadLocalRandom}} which is an implementation of the same
SplitMix64 algorithm introduced in JDK 1.7. Here are the test methods:
 * threadLocalRandom: Use {{ThreadLocalRandom.current()}}
 * threadLocalRandomWrapped: Wrap {{ThreadLocalRandom.current()}} with the {{UniformRandomProvider}}
interface
 * randomSourceCreate: Create a new generator using {{RandomSource.create}}
 * threadLocalRandomSourceCurrent: Use the new {{ThreadLocalRandomSource.current()}} method

Run using 4 threads:
||numValues||randomSourceName||Method||Score||Relative||
|1|MWC_256|randomSourceCreate|26.1|5825.89|
|1|SPLIT_MIX_64|randomSourceCreate|0.798|178.13|
|1|N/A|threadLocalRandom|0.00448|1.00|
|1|N/A|threadLocalRandomWrapped|0.0045|1.00|
|1|MWC_256|threadLocalRandomSourceCurrent|0.0131|2.92|
|1|SPLIT_MIX_64|threadLocalRandomSourceCurrent|0.00977|2.18|
|10|MWC_256|randomSourceCreate|27|1467.39|
|10|SPLIT_MIX_64|randomSourceCreate|0.791|42.99|
|10|N/A|threadLocalRandom|0.0184|1.00|
|10|N/A|threadLocalRandomWrapped|0.0208|1.13|
|10|MWC_256|threadLocalRandomSourceCurrent|0.0594|3.23|
|10|SPLIT_MIX_64|threadLocalRandomSourceCurrent|0.0294|1.60|
|100|MWC_256|randomSourceCreate|26.6|170.51|
|100|SPLIT_MIX_64|randomSourceCreate|0.818|5.24|
|100|N/A|threadLocalRandom|0.156|1.00|
|100|N/A|threadLocalRandomWrapped|0.197|1.26|
|100|MWC_256|threadLocalRandomSourceCurrent|0.475|3.04|
|100|SPLIT_MIX_64|threadLocalRandomSourceCurrent|0.162|1.04|

Creating a new generator each time is slow.

ThreadLocalRandom is fastest. But then has to be wrapped if it is to be used for any class
that requires a UniformRandomProvider.

Once 10 samples are required for the short lived generator the new {{ThreadLocalRandomSource}}
is performing well, and once 100 samples are required then the wrapped {{ThreadLocalRandom}}
is outperformed by the thread-local {{SplitMix}}.

I am not sure of the slow time for the {{MWC_256}} when used thread-locally. The user guide
timings indicate that this should be about 1.5x slower than SplitMix for generation of {{long}}
values. However I did not use a {{BlackHole}} to consume values and just returned the combination
of all values using {{xor}}.

I will try some more generators, longer generation sequences, using a {{BlackHole}} and another
machine. However I believe the new class achieves the aim of making local thread-safe short
lived generators readily available.

Code can be inspected in [PR 27|https://github.com/apache/commons-rng/pull/27].

 

> ThreadLocalRandomSource
> -----------------------
>
>                 Key: RNG-78
>                 URL: https://issues.apache.org/jira/browse/RNG-78
>             Project: Commons RNG
>          Issue Type: New Feature
>          Components: simple
>    Affects Versions: 1.3
>            Reporter: Alex D Herbert
>            Assignee: Alex D Herbert
>            Priority: Minor
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Implement a helper class that can provide thread-local {{UniformRandomProvider}} instances. 
> This can be used as an equivalent of {{ThreadLocalRandom}}:
> {code:java}
> // c.f.
> Random random = ThreadLocalRandom.current();
> // Access a thread-safe random number generator
> UniformRandomProvider rng = 
>     ThreadLocalRandomSource.current(RandomSource.SPLIT_MIX_64);
> {code}



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

Mime
View raw message