Ocean
Loading...
Searching...
No Matches
RandomGenerator.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_RANDOM_GENERATOR_H
9#define META_OCEAN_BASE_RANDOM_GENERATOR_H
10
11#include "ocean/base/Base.h"
12#include "ocean/base/Lock.h"
13
14#include <cstdlib>
15
16namespace Ocean
17{
18
19/**
20 * This class implements a generator for random numbers.
21 * A random generator object can be used to improve the performance of code (needing random numbers) which is applied on several CPU cores in parallel.<br>
22 * The default random number functions of the standard library are thread-safe but may apply expensive locks to synchronize the individual seed parameters of the individual threads.<br>
23 * Therefore, this class can be used to improve the code performance significantly in multi-threaded environments.<br>
24 * The following code example shows the correct application of this class for multi-core functions (which can be invoked e.g., by the Worker class):<br>
25 * @code
26 * void multiCoreFunction(RandomGenerator& randomGenerator, unsigned int* data, unsigned int firstObject, unsigned int numberObjects)
27 * {
28 * /// create a local random generator object which uses the function's random generator to create a new seed value
29 * RandomGenerator localRandomGenerator(randomGenerator);
30 *
31 * for (unsigned int n = firstObject; n <= firstObject + numberObjects; ++n)
32 * {
33 * /// we create random values and use the local random generator (not the function's random generator)
34 * data[n] = RandomI::random(localRandomGenerator, 100u);
35 * }
36 * }
37 * @endcode
38 * @see RandomI, Worker.
39 * @ingroup base
40 */
41class OCEAN_BASE_EXPORT RandomGenerator
42{
43 public:
44
45 /**
46 * Creates a new random generator and initializes the internal parameter with the random value of the standard random function.
47 * Ensure that RandomI::initialize() has been called before using this constructor.
48 * @see RandomI::initialize().
49 */
51
52 /**
53 * Creates a new random generator and initializes the internal parameter by a random value provided by the locked random function of the given generator.
54 * @param generator Random number generator used for initialization, the generator's seed will be changed during the initialization
55 */
56 explicit inline RandomGenerator(RandomGenerator& generator);
57
58 /**
59 * Creates a new random generator and optional initializes the internal parameter by a random value provided by the locked random function of the given generator, if no generator is provided the standard random function will be used for initialization.
60 * @param optionalGenerator The random number generator used for initialization (the generator's seed will be changed during the initialization), nullptr to use the standard random function for initialization
61 */
62 explicit RandomGenerator(RandomGenerator* optionalGenerator);
63
64 /**
65 * Move constructor.
66 * @param randomGenerator The random generator object to be moved
67 */
68 inline RandomGenerator(RandomGenerator&& randomGenerator);
69
70 /**
71 * Creates a new random generator and initializes the internal parameter by the given value.
72 * @param seed The seed initialization value, with range [0, infinity)
73 */
74 explicit inline RandomGenerator(const unsigned int seed);
75
76 /**
77 * Returns the next random number.
78 * Beware: This function is not thread safe.
79 * @return Random number with range [0, 32767]
80 * @see lockedRand().
81 */
82 inline unsigned int rand();
83
84 /**
85 * Returns the next random number.
86 * This function is thread safe.
87 * @return Random number with range [0, 32767]
88 * @see rand().
89 */
90 inline unsigned int lockedRand();
91
92 /**
93 * Returns the current seed value of this object.
94 * This seed value changes whenever a new random number is generated.
95 * @return Current seed value
96 */
97 inline unsigned int seed() const;
98
99 /**
100 * Returns the initial seed value which was used to initialize this random generator.
101 * The initial seed value will not change during the lifetime of the generator.
102 * @return The random generator's initial seed value
103 */
104 inline unsigned int initialSeed() const;
105
106 /**
107 * Move operator.
108 * @param randomGenerator The random generator object to be moved
109 * @return Reference to this object
110 */
112
113 /**
114 * Returns the maximal random value of this generator.
115 * @return Maximal random value of this generator
116 */
117 static constexpr unsigned int randMax();
118
119 private:
120
121 /**
122 * Returns a seed value based on the current time, the thread id, and a random value from RandomI.
123 * @return The combined seed value
124 */
125 static unsigned int threadAndTimeBasedSeed();
126
127 private:
128
129 /// The seed value which was used to initialize this random generator.
130 unsigned int initialSeed_ = (unsigned int)(-1);
131
132 /// Internal seed parameter used for random number generation, changes whenever a new random number is generated.
133 unsigned int seed_ = (unsigned int)(-1);
134
135 /// Generator lock.
137};
138
140{
141 const unsigned int seedLow = generator.lockedRand() & 0xFFFFu;
142 const unsigned int seedHigh = (generator.lockedRand() & 0xFFFFu) << 16u;
143
144 initialSeed_ = seedLow | seedHigh;
145
146 // doing first randomization step
147 seed_ = initialSeed_ * 214013L + 2531011L;
148}
149
150inline RandomGenerator::RandomGenerator(const unsigned int seed) :
151 initialSeed_(seed)
152{
154}
155
157{
158 *this = std::move(randomGenerator);
159}
160
161inline unsigned int RandomGenerator::rand()
162{
163 return (unsigned int)(((seed_ = seed_ * 214013L + 2531011L) >> 16) & 0x7fff);
164}
165
166inline unsigned int RandomGenerator::lockedRand()
167{
168 const ScopedLock scopedLock(lock_);
169
170 return (unsigned int)(((seed_ = seed_ * 214013L + 2531011L) >> 16) & 0x7fff);
171}
172
173inline unsigned int RandomGenerator::seed() const
174{
175 return seed_;
176}
177
178inline unsigned int RandomGenerator::initialSeed() const
179{
180 return initialSeed_;
181}
182
183constexpr unsigned int RandomGenerator::randMax()
184{
185 return 0x7fffu;
186}
187
188}
189
190#endif // META_OCEAN_BASE_RANDOM_GENERATOR_H
This class implements a recursive lock object.
Definition Lock.h:31
This class implements a generator for random numbers.
Definition RandomGenerator.h:42
Lock lock_
Generator lock.
Definition RandomGenerator.h:136
static unsigned int threadAndTimeBasedSeed()
Returns a seed value based on the current time, the thread id, and a random value from RandomI.
unsigned int lockedRand()
Returns the next random number.
Definition RandomGenerator.h:166
unsigned int rand()
Returns the next random number.
Definition RandomGenerator.h:161
static constexpr unsigned int randMax()
Returns the maximal random value of this generator.
Definition RandomGenerator.h:183
unsigned int initialSeed_
The seed value which was used to initialize this random generator.
Definition RandomGenerator.h:130
unsigned int seed() const
Returns the current seed value of this object.
Definition RandomGenerator.h:173
unsigned int initialSeed() const
Returns the initial seed value which was used to initialize this random generator.
Definition RandomGenerator.h:178
RandomGenerator & operator=(RandomGenerator &&randomGenerator)
Move operator.
unsigned int seed_
Internal seed parameter used for random number generation, changes whenever a new random number is ge...
Definition RandomGenerator.h:133
RandomGenerator(RandomGenerator *optionalGenerator)
Creates a new random generator and optional initializes the internal parameter by a random value prov...
RandomGenerator()
Creates a new random generator and initializes the internal parameter with the random value of the st...
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:135
The namespace covering the entire Ocean framework.
Definition Accessor.h:15