RFR(S) : 8243429 : use reproducible random in :vmTestbase_nsk_stress
David Holmes
david.holmes at oracle.com
Fri May 1 05:52:21 UTC 2020
On 1/05/2020 3:20 pm, Igor Ignatyev wrote:
>> On Apr 30, 2020, at 9:52 PM, David Holmes <david.holmes at oracle.com
>> <mailto:david.holmes at oracle.com>> wrote:
>>
>> On 1/05/2020 2:30 pm, Igor Ignatyev wrote:
>>>> On Apr 30, 2020, at 9:14 PM, David Holmes <david.holmes at oracle.com
>>>> <mailto:david.holmes at oracle.com><mailto:david.holmes at oracle.com>> wrote:
>>>>
>>>> On 1/05/2020 1:27 pm, Igor Ignatyev wrote:
>>>>> Hi David,
>>>>>> On Apr 30, 2020, at 7:34 PM, David Holmes <david.holmes at oracle.com
>>>>>> <mailto:david.holmes at oracle.com>
>>>>>> <mailto:david.holmes at oracle.com><mailto:david.holmes at oracle.com>>
>>>>>> wrote:
>>>>>>
>>>>>> Hi Igor,
>>>>>>
>>>>>> On 1/05/2020 3:15 am, Igor Ignatyev wrote:
>>>>>>> http://cr.openjdk.java.net/~iignatyev/8243429/webrev.00
>>>>>>>> 82 lines changed: 41 ins; 4 del; 37 mod;
>>>>>>
>>>>>> The patch files in your webrevs are not generating properly due to
>>>>>> the use of mq. can you fix that?
>>>>> unfortunately, I've already squashed all the patches together, so I
>>>>> was able to upload only the final version --
>>>>> http://cr.openjdk.java.net/~iignatyev/8243429/webrev.00/8243429.patch
>>>>>>
>>>>>>> Hi all,
>>>>>>> could you please review this small patch?
>>>>>>> from JBS:
>>>>>>>> this subtask is to use j.t.l.Utils.getRandomInstance() as a
>>>>>>>> random number generator, where applicable, in
>>>>>>>> :vmTestbase_nsk_stress test group and marking the tests which
>>>>>>>> make use of "randomness" with a proper k/w.
>>>>>>
>>>>>> I'm a bit confused about the strategy here:
>>>>>>
>>>>>> vmTestbase/nsk/stress/except/except012.java
>>>>>>
>>>>>> - Random random = new Random(0);
>>>>>> + Random random = new Random(42);
>>>>>>
>>>>>> but:
>>>>>>
>>>>>> vmTestbase/nsk/stress/jni/jnistress002.java
>>>>>>
>>>>>> - static Random myRandom = new Random();
>>>>>> + Random myRandom = new
>>>>>> Random(Utils.getRandomInstance().nextLong());
>>>>>>
>>>>>> why are these random instances seeded completely differently?
>>>>> because they were different before my patch, except012 used a fixed
>>>>> seed (so it doesn't qualify to be marked w/ randomness k/w), and
>>>>> jnistress002 used a "random" seed; after the patch except012 still
>>>>> uses a fixed (but a "well-known" and easier to grep) seed value,
>>>>> and jnistress002 uses random, yet reproducible/configurable seed.
>>>>> I've explained that in my previous RFRs for hotspot tests outside
>>>>> of vmTestbase, e.g.
>>>>> https://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2020-April/037828.html
>>>>
>>>> Not everyone on hotspot-dev is also on hotspot-compiler-dev.
>>> true, yet almost every hotspot-X-dev alias received their porting of
>>> 'use reproducible random in hotspot X tests' a couple weeks ago,
>>> which all have references to the same email thread ;) . in any case,
>>> I apologize I should have provided enough context in each of new RFR.
>>>>
>>>> I'm trying to understand why we still have different usage patterns.
>>>> IIUC there's no reason that except012 couldn't be seeded the same
>>>> way as jnistress002 - right? Then it would qualify for "randomness"
>>>> keyword. What is it about any given test that determines whether we
>>>> seed the RNG differently on each test run versus fixing it at 42
>>>> (for example)?
>>> it's more the question for the author of particular test. I didn't
>>> plan to (significantly) change behavior of the tests, so I tried not
>>> to convert any non "randomness" tests to "randomness" tests.
>>
>> Okay. But making changes in this area it just draws attention to the
>> different way we do things, and it is n't obvious why there are
>> differnet ways.
> I guess that some people decided to use fixed seed so their tests are
> more-or-less stable to themselves and results from different runs can be
> compared; yet others decided that they would like their tests to cover
> different paths in different runs. and I really don't know which
> solution is better, but I believe that solution which allows you to get
> the best of both is the best. that's to say, I'll definitely file a task
> to look into all places we use fixed seed in hotspot tests and see if it
> makes sense to switch to a "random" seed value, and will work on it as
> part of switching to CI-run/build-based seed or, as you called it in
> another thread, "one blessed seed". thank you for all these discussions!
Sounds good. Sorry for drawing this out so much.
>>
>>>>
>>>>> also, in jnistress002, we can't use Utils.getRandomInstance() as
>>>>> there would multiple threads (JNIter002) using the same RNG. we
>>>>> could change it to use LocalRandom, I must admit I was doing
>>>>> different parts of these patches on different days, and given their
>>>>> tediousness I might have became less consistent in my choices b/w
>>>>> using LocalRandom and using a "threadlocal" instance of Random. I,
>>>>> personally, think we need to switch to LocalRandom in all such
>>>>> cases, or even better to replace Utils.getRandomInstance() w/
>>>>> something akin to LocalRandom, but such change is somewhat
>>>>> orthogonal to the series of 'use reproducible random' patches, so
>>>>> I'd prefer to do it separately.
>>>>
>>>> Sure but it remains confusing to see such a variety of cases.
>>>> Utils.getRandomInstance() is a shared RNG so you never want to use
>>>> that directly in different threads if you truly want reproducability
>>>> - the most you can use it for is the source of seeds for other RNGs
>>>> - but even that is non-deterministic is different threads are involved.
>>> right, that's why I think it's better/safer to use something similar
>>> to LocalRandom in all tests w/o thinking if it's multi-threaded or not.
>>>> So your changes from Math.random are not going to be reproducible
>>>> due to different threads being involved.
>>> really? could you please point me to the test/tests which used
>>> Math.random and now have multiple threads using the same instance of
>>> Random?
>>
>> Apologies. On examining the numeric* tests in detail it seems the RNG
>> is only used during the setup phase.
>>
>>>>
>>>>>>
>>>>>> And looking at:
>>>>>>
>>>>>> vmTestbase/nsk/stress/jni/gclocker/gcl001.java
>>>>>>
>>>>>> you changed it to use the LocalRandom utility rather than creating
>>>>>> its own random instance. Why was that applicable here but not in
>>>>>> other tests?
>>>>>>
>>>>>> The changes from Math.random to a local RNG from
>>>>>> getRandomInstance() seem okay- but again why that versus
>>>>>> LocalRandom? Do we even need LocalRandom?
>>>>> (although I guess you've already figured that out from other
>>>>> patches, I'll answer here for completeness)
>>>>> vmTestbase/nsk/stress/jni/gclocker/gcl001.java used the same
>>>>> instance of RNG in multiple threads, hence it would be really
>>>>> reproducible if we just switched to getRandomInstance(),
>>>>> LocalRandom is needed exactly for that -- provide reproducible
>>>>> random in multi-thread use cases.
>>>>
>>>> I'm not sure if you wrote that exactly as intended.
>>>> Utils.getRandomInstance() does not produce a RNG that gives
>>>> reproducible results across threads, so we should, it seems, never
>>>> use it directly in any multi-threaded stress test.
>>> sorry, I missed 'not', it should have been 'hence it would not be
>>> really reproducible'
>>>> Secondly, LocalRandom is a wrapper for ThreadLocalRandom.current()
>>>> _but_ you have no control over the seed so seems not so useful for
>>>> achieving reproducability!
>>> I guess you haven't updated your workspace, LocalRandom is now (after
>>> 8242314) using ThreadLocal<Random>:
>>>> private final static ThreadLocal<Random> random = new ThreadLocal<>() {
>>>> protected Random initialValue() {
>>>> // each thread gets its own seed independendly on the
>>>> order they
>>>> // use LocalRandom, yet it depends on the order threads
>>>> are created.
>>>> // main thread uses original seed
>>>> return new Random(Utils.SEED ^
>>>> (Thread.currentThread().getId() - 1));
>>>> }
>>>> };
>>
>> Ah yes - sorry - my local repo on my laptop (only used for code
>> browsing) was missing that change. Okay that makes a big difference :)
>>
>> However I will note that using the thread ID as part of the seed may
>> not lead to reproducible results if the thread creation itself is not
>> deterministic/reproducible.
> true, yet in most cases it's still better than prev. solution, and it's
> never worse. and in all of my runs w/ instrumented builds, thread
> creation and hence the seeds were deterministic.
Definitely better than before. :)
I would have to wonder whether dynamic compiler threads would be the
mostly likely source of disruption.
> so,.. can I count you as a reviewer?
Of course :)
Thanks,
David
> -- Igor
>>
>> Thanks,
>> David
>>
>>> -- Igor
>>>>
>>>> David
>>>> -----
>>>>
>>>>> -- Igor
>>>>>>
>>>>>> Thanks,
>>>>>> David
>>>>>>
>>>>>>> testing: : vmTestbase_nsk_stress test group
>>>>>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8243429
>>>>>>> webrevs:
>>>>>>> - code changes:
>>>>>>> http://cr.openjdk.java.net/~iignatyev//8243429/webrev.00.code
>>>>>>>> 58 lines changed: 41 ins; 4 del; 13 mod;
>>>>>>> - adding k/w:
>>>>>>> http://cr.openjdk.java.net/~iignatyev//8243429/webrev.00.kw
>>>>>>>> 11 lines changed: 0 ins; 0 del; 11 mod;
>>>>>>> - full: http://cr.openjdk.java.net/~iignatyev//8243429/webrev.00
>>>>>>>> 82 lines changed: 41 ins; 4 del; 37 mod;
>>>>>>> Thanks,
>>>>>>> -- Igor
>
More information about the hotspot-dev
mailing list