View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.rng.examples.jmh.simple;
19  
20  import org.apache.commons.rng.UniformRandomProvider;
21  import org.apache.commons.rng.core.source64.SplitMix64;
22  import org.apache.commons.rng.simple.RandomSource;
23  import org.apache.commons.rng.simple.internal.SeedFactory;
24  import org.openjdk.jmh.annotations.Benchmark;
25  import org.openjdk.jmh.annotations.BenchmarkMode;
26  import org.openjdk.jmh.annotations.Fork;
27  import org.openjdk.jmh.annotations.Measurement;
28  import org.openjdk.jmh.annotations.Mode;
29  import org.openjdk.jmh.annotations.OutputTimeUnit;
30  import org.openjdk.jmh.annotations.Scope;
31  import org.openjdk.jmh.annotations.State;
32  import org.openjdk.jmh.annotations.Threads;
33  import org.openjdk.jmh.annotations.Warmup;
34  
35  import java.util.Random;
36  import java.util.concurrent.ThreadLocalRandom;
37  import java.util.concurrent.TimeUnit;
38  import java.util.concurrent.atomic.AtomicInteger;
39  import java.util.concurrent.atomic.AtomicLong;
40  import java.util.concurrent.locks.Lock;
41  import java.util.concurrent.locks.ReentrantLock;
42  
43  /**
44   * Executes a benchmark to compare the speed of generating a single {@code int/long} value
45   * in a thread-safe way.
46   */
47  @BenchmarkMode(Mode.AverageTime)
48  @OutputTimeUnit(TimeUnit.NANOSECONDS)
49  @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
50  @Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
51  @State(Scope.Benchmark)
52  @Fork(value = 1, jvmArgs = {"-server", "-Xms512M", "-Xmx512M"})
53  public class SeedGenerationPerformance {
54      /**
55       * The increment of the seed per new instance.
56       * This is copied from ThreadLocalRandom.
57       */
58      static final long SEED_INCREMENT = 0xbb67ae8584caa73bL;
59  
60      /**
61       * The lock to own when using the generator. This lock is unfair and there is no
62       * particular access order for waiting threads.
63       *
64       * <p>This is used as an alternative to {@code synchronized} statements.</p>
65       */
66      private static final ReentrantLock UNFAIR_LOCK = new ReentrantLock(false);
67  
68      /**
69       * The lock to own when using the generator. This lock is fair and the longest waiting
70       * thread will be favoured.
71       *
72       * <p>This is used as an alternative to {@code synchronized} statements.</p>
73       */
74      private static final ReentrantLock FAIR_LOCK = new ReentrantLock(true);
75  
76      /**
77       * A representation of the golden ratio converted to a long:
78       * 2^64 * phi where phi = (sqrt(5) - 1) / 2.
79       */
80      private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
81  
82      /** The int value. Must NOT be final to prevent JVM optimisation! */
83      private int intValue;
84  
85      /** The long value. Must NOT be final to prevent JVM optimisation! */
86      private long longValue;
87  
88      /** The int value to use for 'randomness'. */
89      private volatile int volatileIntValue;
90  
91      /** The long value to use for 'randomness'. */
92      private volatile long volatileLongValue;
93  
94      /** The Atomic integer to use for 'randomness'. */
95      private final AtomicInteger atomicInt = new AtomicInteger();
96  
97      /** The Atomic long to use for 'randomness'. */
98      private final AtomicLong atomicLong = new AtomicLong();
99  
100     /** The state of the SplitMix generator. */
101     private final AtomicLong state = new AtomicLong();
102 
103     /** The XoRoShiRo128Plus RNG. */
104     private final UniformRandomProvider xoRoShiRo128Plus = RandomSource.XO_RO_SHI_RO_128_PLUS.create();
105 
106     /** The XorShift1024StarPhi RNG. */
107     private final UniformRandomProvider xorShift1024StarPhi = RandomSource.XOR_SHIFT_1024_S_PHI.create();
108 
109     /** The Well44497b RNG. */
110     private final UniformRandomProvider well44497b = RandomSource.WELL_44497_B.create();
111 
112     /** The JDK Random instance (the implementation is thread-safe). */
113     private final Random random = new Random();
114 
115     /**
116      * Extend the {@link ThreadLocal} to allow creation of a local generator.
117      */
118     private static final class ThreadLocalRNG extends ThreadLocal<UniformRandomProvider> {
119         /**
120          * The seed for constructors.
121          */
122         private static final AtomicLong SEED = new AtomicLong(0);
123 
124         /** Instance. */
125         private static final ThreadLocalRNG INSTANCE = new ThreadLocalRNG();
126 
127         /** No public construction. */
128         private ThreadLocalRNG() {
129             // Do nothing. The seed could be initialized here.
130         }
131 
132         @Override
133         protected UniformRandomProvider initialValue() {
134             return new SplitMix64(SEED.getAndAdd(SEED_INCREMENT));
135         }
136 
137         /**
138          * Get the current thread's RNG.
139          *
140          * @return the uniform random provider
141          */
142         public static UniformRandomProvider current() {
143             return INSTANCE.get();
144         }
145     }
146 
147     /**
148      * Extend the {@link ThreadLocal} to allow creation of a local generator.
149      */
150     private static final class ThreadLocalSplitMix extends ThreadLocal<SplitMix64> {
151         /**
152          * The seed for constructors.
153          */
154         private static final AtomicLong SEED = new AtomicLong(0);
155 
156         /** Instance. */
157         private static final ThreadLocalSplitMix INSTANCE = new ThreadLocalSplitMix();
158 
159         /** No public construction. */
160         private ThreadLocalSplitMix() {
161             // Do nothing. The seed could be initialized here.
162         }
163 
164         @Override
165         protected SplitMix64 initialValue() {
166             return new SplitMix64(SEED.getAndAdd(SEED_INCREMENT));
167         }
168 
169         /**
170          * Get the current thread's RNG.
171          *
172          * @return the uniform random provider
173          */
174         public static SplitMix64 current() {
175             return INSTANCE.get();
176         }
177     }
178 
179     /**
180      * Extend the {@link ThreadLocal} to allow creation of a local sequence.
181      */
182     private static final class ThreadLocalSequence extends ThreadLocal<long[]> {
183         /**
184          * The seed for constructors.
185          */
186         private static final AtomicLong SEED = new AtomicLong(0);
187 
188         /** Instance. */
189         private static final ThreadLocalSequence INSTANCE = new ThreadLocalSequence();
190 
191         /** No public construction. */
192         private ThreadLocalSequence() {
193             // Do nothing. The seed could be initialized here.
194         }
195 
196         @Override
197         protected long[] initialValue() {
198             return new long[] {SEED.getAndAdd(SEED_INCREMENT)};
199         }
200 
201         /**
202          * Get the current thread's next sequence value.
203          *
204          * @return the next value
205          */
206         public static long next() {
207             final long[] value = INSTANCE.get();
208             return value[0] += GOLDEN_GAMMA;
209         }
210     }
211 
212     /**
213      * Get the next {@code int} from the RNG. This is synchronized on the generator.
214      *
215      * @param rng Random generator.
216      * @return the int
217      */
218     private static int nextInt(UniformRandomProvider rng) {
219         synchronized (rng) {
220             return rng.nextInt();
221         }
222     }
223 
224     /**
225      * Get the next {@code long} from the RNG. This is synchronized on the generator.
226      *
227      * @param rng Random generator.
228      * @return the long
229      */
230     private static long nextLong(UniformRandomProvider rng) {
231         synchronized (rng) {
232             return rng.nextLong();
233         }
234     }
235 
236     /**
237      * Get the next {@code int} from the RNG. The lock is used to guard access to the generator.
238      *
239      * @param lock Lock guarding access to the generator.
240      * @param rng Random generator.
241      * @return the int
242      */
243     private static int nextInt(Lock lock, UniformRandomProvider rng) {
244         lock.lock();
245         try {
246             return rng.nextInt();
247         } finally {
248             lock.unlock();
249         }
250     }
251 
252     /**
253      * Get the next {@code long} from the RNG. The lock is used to guard access to the generator.
254      *
255      * @param lock Lock guarding access to the generator.
256      * @param rng Random generator.
257      * @return the long
258      */
259     private static long nextLong(Lock lock, UniformRandomProvider rng) {
260         lock.lock();
261         try {
262             return rng.nextLong();
263         } finally {
264             lock.unlock();
265         }
266     }
267 
268     /**
269      * Perform the mixing step from the SplitMix algorithm. This is the Stafford variant
270      * 13 mix64 function.
271      *
272      * @param z the input value
273      * @return the output value
274      * @see <a
275      * href="http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html">Better
276      * Bit Mixing</a>
277      */
278     private static long mixLong(long z) {
279         z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
280         z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
281         return z ^ (z >>> 31);
282     }
283 
284     /**
285      * Perform the 32-bit mixing step from the SplittableRandom algorithm. Note this is
286      * the 32 high bits of Stafford variant 4 mix64 function as int.
287      *
288      * @param z the input value
289      * @return the output value
290      * @see <a
291      * href="http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html">Better
292      * Bit Mixing</a>
293      */
294     private static int mixInt(long z) {
295         z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
296         return (int) (((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
297     }
298 
299     /**
300      * Baseline for a JMH method call with no return value.
301      */
302     @Benchmark
303     public void baselineVoid() {
304         // Do nothing, this is a baseline
305     }
306 
307     /**
308      * Baseline for a JMH method call returning an {@code int}.
309      *
310      * @return the value
311      */
312     @Benchmark
313     public int baselineInt() {
314         return intValue;
315     }
316 
317     /**
318      * Baseline for a JMH method call returning an {@code long}.
319      *
320      * @return the value
321      */
322     @Benchmark
323     public long baselineLong() {
324         return longValue;
325     }
326 
327     // The following methods use underscores to make parsing the results output easier.
328     // They are not documented as the names are self-documenting.
329 
330     // CHECKSTYLE: stop MethodName
331     // CHECKSTYLE: stop JavadocMethod
332     // CHECKSTYLE: stop DesignForExtension
333 
334     @Benchmark
335     public int XoRoShiRo128Plus_nextInt() {
336         return xoRoShiRo128Plus.nextInt();
337     }
338 
339     @Benchmark
340     public int XorShift1024StarPhi_nextInt() {
341         return xorShift1024StarPhi.nextInt();
342     }
343 
344     @Benchmark
345     public int Well44497b_nextInt() {
346         return well44497b.nextInt();
347     }
348 
349     @Benchmark
350     public long XoRoShiRo128Plus_nextLong() {
351         return xoRoShiRo128Plus.nextLong();
352     }
353 
354     @Benchmark
355     public long XorShift1024StarPhi_nextLong() {
356         return xorShift1024StarPhi.nextLong();
357     }
358 
359     @Benchmark
360     public long Well44497b_nextLong() {
361         return well44497b.nextLong();
362     }
363 
364     @Benchmark
365     public int Threads1_SeedFactory_createInt() {
366         return SeedFactory.createInt();
367     }
368 
369     @Benchmark
370     public long Threads1_SeedFactory_createLong() {
371         return SeedFactory.createLong();
372     }
373 
374     @Benchmark
375     public long Threads1_System_currentTimeMillis() {
376         // This may not be unique per call and is not random.
377         return System.currentTimeMillis();
378     }
379 
380     @Benchmark
381     public long Threads1_System_nanoTime() {
382         // This is not random.
383         return System.nanoTime();
384     }
385 
386     @Benchmark
387     public int Threads1_System_identityHashCode() {
388         return System.identityHashCode(new Object());
389     }
390 
391     @Benchmark
392     public long Threads1_ThreadLocalRandom_nextLong() {
393         return ThreadLocalRandom.current().nextLong();
394     }
395 
396     @Benchmark
397     public int Threads1_ThreadLocalRandom_nextInt() {
398         return ThreadLocalRandom.current().nextInt();
399     }
400 
401     @Benchmark
402     public long Threads1_ThreadLocalRNG_nextLong() {
403         return ThreadLocalRNG.current().nextLong();
404     }
405 
406     @Benchmark
407     public int Threads1_ThreadLocalRNG_nextInt() {
408         return ThreadLocalRNG.current().nextInt();
409     }
410 
411     @Benchmark
412     public long Threads1_ThreadLocalSplitMix_nextLong() {
413         return ThreadLocalSplitMix.current().nextLong();
414     }
415 
416     @Benchmark
417     public int Threads1_ThreadLocalSplitMix_nextInt() {
418         return ThreadLocalSplitMix.current().nextInt();
419     }
420 
421     @Benchmark
422     public long Threads1_ThreadLocalSequenceMix_nextLong() {
423         return mixLong(ThreadLocalSequence.next());
424     }
425 
426     @Benchmark
427     public int Threads1_ThreadLocalSequenceMix_nextInt() {
428         return mixInt(ThreadLocalSequence.next());
429     }
430 
431     @Benchmark
432     public long Threads1_Random_nextLong() {
433         return random.nextLong();
434     }
435 
436     @Benchmark
437     public int Threads1_Random_nextInt() {
438         return random.nextInt();
439     }
440 
441     @Benchmark
442     public long Threads1_SyncSplitMix_nextLong() {
443         return mixLong(state.getAndAdd(GOLDEN_GAMMA));
444     }
445 
446     @Benchmark
447     public int Threads1_SyncSplitMix_nextInt() {
448         return mixInt(state.getAndAdd(GOLDEN_GAMMA));
449     }
450 
451     @Benchmark
452     public int Threads1_Sync_XoRoShiRo128Plus_nextInt() {
453         return nextInt(xoRoShiRo128Plus);
454     }
455 
456     @Benchmark
457     public int Threads1_Sync_XorShift1024StarPhi_nextInt() {
458         return nextInt(xorShift1024StarPhi);
459     }
460 
461     @Benchmark
462     public int Threads1_Sync_Well44497b_nextInt() {
463         return nextInt(well44497b);
464     }
465 
466     @Benchmark
467     public long Threads1_Sync_XoRoShiRo128Plus_nextLong() {
468         return nextLong(xoRoShiRo128Plus);
469     }
470 
471     @Benchmark
472     public long Threads1_Sync_XorShift1024StarPhi_nextLong() {
473         return nextLong(xorShift1024StarPhi);
474     }
475 
476     @Benchmark
477     public long Threads1_Sync_Well44497b_nextLong() {
478         return nextLong(well44497b);
479     }
480 
481     @Benchmark
482     public int Threads1_UnfairLock_XoRoShiRo128Plus_nextInt() {
483         return nextInt(UNFAIR_LOCK, xoRoShiRo128Plus);
484     }
485 
486     @Benchmark
487     public int Threads1_UnfairLock_XorShift1024StarPhi_nextInt() {
488         return nextInt(UNFAIR_LOCK, xorShift1024StarPhi);
489     }
490 
491     @Benchmark
492     public int Threads1_UnfairLock_Well44497b_nextInt() {
493         return nextInt(UNFAIR_LOCK, well44497b);
494     }
495 
496     @Benchmark
497     public long Threads1_UnfairLock_XoRoShiRo128Plus_nextLong() {
498         return nextLong(UNFAIR_LOCK, xoRoShiRo128Plus);
499     }
500 
501     @Benchmark
502     public long Threads1_UnfairLock_XorShift1024StarPhi_nextLong() {
503         return nextLong(UNFAIR_LOCK, xorShift1024StarPhi);
504     }
505 
506     @Benchmark
507     public long Threads1_UnfairLock_Well44497b_nextLong() {
508         return nextLong(UNFAIR_LOCK, well44497b);
509     }
510 
511     @Benchmark
512     public int Threads1_FairLock_XoRoShiRo128Plus_nextInt() {
513         return nextInt(FAIR_LOCK, xoRoShiRo128Plus);
514     }
515 
516     @Benchmark
517     public int Threads1_FairLock_XorShift1024StarPhi_nextInt() {
518         return nextInt(FAIR_LOCK, xorShift1024StarPhi);
519     }
520 
521     @Benchmark
522     public int Threads1_FairLock_Well44497b_nextInt() {
523         return nextInt(FAIR_LOCK, well44497b);
524     }
525 
526     @Benchmark
527     public long Threads1_FairLock_XoRoShiRo128Plus_nextLong() {
528         return nextLong(FAIR_LOCK, xoRoShiRo128Plus);
529     }
530 
531     @Benchmark
532     public long Threads1_FairLock_XorShift1024StarPhi_nextLong() {
533         return nextLong(FAIR_LOCK, xorShift1024StarPhi);
534     }
535 
536     @Benchmark
537     public long Threads1_FairLock_Well44497b_nextLong() {
538         return nextLong(FAIR_LOCK, well44497b);
539     }
540 
541     @Benchmark
542     public int Threads1_volatileInt_increment() {
543         return ++volatileIntValue;
544     }
545 
546     @Benchmark
547     public long Threads1_volatileLong_increment() {
548         return ++volatileLongValue;
549     }
550 
551     @Benchmark
552     public int Threads1_AtomicInt_getAndIncrement() {
553         return atomicInt.getAndIncrement();
554     }
555 
556     @Benchmark
557     public long Threads1_AtomicLong_getAndIncrement() {
558         return atomicLong.getAndIncrement();
559     }
560 
561     @Benchmark
562     @Threads(4)
563     public int Threads4_SeedFactory_createInt() {
564         return SeedFactory.createInt();
565     }
566 
567     @Benchmark
568     @Threads(4)
569     public long Threads4_SeedFactory_createLong() {
570         return SeedFactory.createLong();
571     }
572 
573     @Benchmark
574     @Threads(4)
575     public long Threads4_System_currentTimeMillis() {
576         // This may not be unique per call and is not random.
577         return System.currentTimeMillis();
578     }
579 
580     @Benchmark
581     @Threads(4)
582     public long Threads4_System_nanoTime() {
583         // This is not random.
584         return System.nanoTime();
585     }
586 
587     @Benchmark
588     @Threads(4)
589     public int Threads4_System_identityHashCode() {
590         return System.identityHashCode(new Object());
591     }
592 
593     @Benchmark
594     @Threads(4)
595     public long Threads4_ThreadLocalRandom_nextLong() {
596         return ThreadLocalRandom.current().nextLong();
597     }
598 
599     @Benchmark
600     @Threads(4)
601     public int Threads4_ThreadLocalRandom_nextInt() {
602         return ThreadLocalRandom.current().nextInt();
603     }
604 
605     @Benchmark
606     @Threads(4)
607     public long Threads4_ThreadLocalRNG_nextLong() {
608         return ThreadLocalRNG.current().nextLong();
609     }
610 
611     @Benchmark
612     @Threads(4)
613     public int Threads4_ThreadLocalRNG_nextInt() {
614         return ThreadLocalRNG.current().nextInt();
615     }
616 
617     @Benchmark
618     @Threads(4)
619     public long Threads4_ThreadLocalSplitMix_nextLong() {
620         return ThreadLocalSplitMix.current().nextLong();
621     }
622 
623     @Benchmark
624     @Threads(4)
625     public int Threads4_ThreadLocalSplitMix_nextInt() {
626         return ThreadLocalSplitMix.current().nextInt();
627     }
628 
629     @Benchmark
630     @Threads(4)
631     public long Threads4_ThreadLocalSequenceMix_nextLong() {
632         return mixLong(ThreadLocalSequence.next());
633     }
634 
635     @Benchmark
636     @Threads(4)
637     public int Threads4_ThreadLocalSequenceMix_nextInt() {
638         return mixInt(ThreadLocalSequence.next());
639     }
640 
641     @Benchmark
642     @Threads(4)
643     public long Threads4_Random_nextLong() {
644         return random.nextLong();
645     }
646 
647     @Benchmark
648     @Threads(4)
649     public int Threads4_Random_nextInt() {
650         return random.nextInt();
651     }
652 
653     @Benchmark
654     @Threads(4)
655     public long Threads4_SyncSplitMix_nextLong() {
656         return mixLong(state.getAndAdd(GOLDEN_GAMMA));
657     }
658 
659     @Benchmark
660     @Threads(4)
661     public int Threads4_SyncSplitMix_nextInt() {
662         return mixInt(state.getAndAdd(GOLDEN_GAMMA));
663     }
664 
665     @Benchmark
666     @Threads(4)
667     public int Threads4_Sync_XoRoShiRo128Plus_nextInt() {
668         return nextInt(xoRoShiRo128Plus);
669     }
670 
671     @Benchmark
672     @Threads(4)
673     public int Threads4_Sync_XorShift1024StarPhi_nextInt() {
674         return nextInt(xorShift1024StarPhi);
675     }
676 
677     @Benchmark
678     @Threads(4)
679     public int Threads4_Sync_Well44497b_nextInt() {
680         return nextInt(well44497b);
681     }
682 
683     @Benchmark
684     @Threads(4)
685     public long Threads4_Sync_XoRoShiRo128Plus_nextLong() {
686         return nextLong(xoRoShiRo128Plus);
687     }
688 
689     @Benchmark
690     @Threads(4)
691     public long Threads4_Sync_XorShift1024StarPhi_nextLong() {
692         return nextLong(xorShift1024StarPhi);
693     }
694 
695     @Benchmark
696     @Threads(4)
697     public long Threads4_Sync_Well44497b_nextLong() {
698         return nextLong(well44497b);
699     }
700 
701     @Benchmark
702     @Threads(4)
703     public int Threads4_UnfairLock_XoRoShiRo128Plus_nextInt() {
704         return nextInt(UNFAIR_LOCK, xoRoShiRo128Plus);
705     }
706 
707     @Benchmark
708     @Threads(4)
709     public int Threads4_UnfairLock_XorShift1024StarPhi_nextInt() {
710         return nextInt(UNFAIR_LOCK, xorShift1024StarPhi);
711     }
712 
713     @Benchmark
714     @Threads(4)
715     public int Threads4_UnfairLock_Well44497b_nextInt() {
716         return nextInt(UNFAIR_LOCK, well44497b);
717     }
718 
719     @Benchmark
720     @Threads(4)
721     public long Threads4_UnfairLock_XoRoShiRo128Plus_nextLong() {
722         return nextLong(UNFAIR_LOCK, xoRoShiRo128Plus);
723     }
724 
725     @Benchmark
726     @Threads(4)
727     public long Threads4_UnfairLock_XorShift1024StarPhi_nextLong() {
728         return nextLong(UNFAIR_LOCK, xorShift1024StarPhi);
729     }
730 
731     @Benchmark
732     @Threads(4)
733     public long Threads4_UnfairLock_Well44497b_nextLong() {
734         return nextLong(UNFAIR_LOCK, well44497b);
735     }
736 
737     @Benchmark
738     @Threads(4)
739     public int Threads4_FairLock_XoRoShiRo128Plus_nextInt() {
740         return nextInt(FAIR_LOCK, xoRoShiRo128Plus);
741     }
742 
743     @Benchmark
744     @Threads(4)
745     public int Threads4_FairLock_XorShift1024StarPhi_nextInt() {
746         return nextInt(FAIR_LOCK, xorShift1024StarPhi);
747     }
748 
749     @Benchmark
750     @Threads(4)
751     public int Threads4_FairLock_Well44497b_nextInt() {
752         return nextInt(FAIR_LOCK, well44497b);
753     }
754 
755     @Benchmark
756     @Threads(4)
757     public long Threads4_FairLock_XoRoShiRo128Plus_nextLong() {
758         return nextLong(FAIR_LOCK, xoRoShiRo128Plus);
759     }
760 
761     @Benchmark
762     @Threads(4)
763     public long Threads4_FairLock_XorShift1024StarPhi_nextLong() {
764         return nextLong(FAIR_LOCK, xorShift1024StarPhi);
765     }
766 
767     @Benchmark
768     @Threads(4)
769     public long Threads4_FairLock_Well44497b_nextLong() {
770         return nextLong(FAIR_LOCK, well44497b);
771     }
772 
773     @Benchmark
774     @Threads(4)
775     public int Threads4_volatileInt_increment() {
776         return ++volatileIntValue;
777     }
778 
779     @Benchmark
780     @Threads(4)
781     public long Threads4_volatileLong_increment() {
782         return ++volatileLongValue;
783     }
784 
785     @Benchmark
786     @Threads(4)
787     public int Threads4_AtomicInt_getAndIncrement() {
788         return atomicInt.getAndIncrement();
789     }
790 
791     @Benchmark
792     @Threads(4)
793     public long Threads4_AtomicLong_getAndIncrement() {
794         return atomicLong.getAndIncrement();
795     }
796 }