-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improved random number generation (#16)
* Implement mt19937 random number generator. - Rendering speed improved up to 10 times. - Need to implement thread-local random number generators. * Fix macOS build errors and off-by-one error. * Add checks for thread_local compiler support. - Fix minor typo when setting compiler flags for debug target. * Add compiler-specific thread local storage. - It turns out that macOS and Windows runners doesn't support thread local variables from C11 - Implementation tested only with Linux so far. - Force Github Actions to use at least 2 threads for rendering. * Fix MSVC detection for thread local storage.
- Loading branch information
1 parent
96aab79
commit 92cec70
Showing
9 changed files
with
159 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/** | ||
* Copyright (c) 2021, Evgeniy Morozov | ||
* All rights reserved. | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
#include <stdlib.h> | ||
#include <assert.h> | ||
#include "rt_random.h" | ||
#include "rt_thread.h" | ||
|
||
struct rt_mt19937_s | ||
{ | ||
int w, n, m, r; | ||
|
||
uint64_t a; | ||
uint64_t u, d; | ||
uint64_t s, b; | ||
uint64_t t, c; | ||
|
||
int l; | ||
uint64_t f; | ||
|
||
uint64_t upper_mask, lower_mask; | ||
|
||
uint64_t index; | ||
uint64_t *MT; | ||
}; | ||
|
||
static RT_THREAD_LOCAL struct rt_mt19937_s gs_generator = { | ||
.index = UINT64_MAX | ||
}; | ||
|
||
static void twist(struct rt_mt19937_s *gen); | ||
|
||
void rt_random_seed(uint64_t seed) | ||
{ | ||
gs_generator.w = 64; | ||
gs_generator.n = 312; | ||
gs_generator.m = 156; | ||
gs_generator.r = 31; | ||
|
||
gs_generator.a = 0xB5026F5AA96619E9ULL; | ||
|
||
gs_generator.u = 29; | ||
gs_generator.d = 0x5555555555555555ULL; | ||
|
||
gs_generator.s = 17; | ||
gs_generator.b = 0x71D67FFFEDA60000; | ||
|
||
gs_generator.t = 37; | ||
gs_generator.c = 0xFFF7EEE000000000; | ||
|
||
gs_generator.l = 43; | ||
|
||
gs_generator.f = 6364136223846793005; | ||
|
||
gs_generator.lower_mask = (1 << gs_generator.r) - 1; | ||
gs_generator.upper_mask = ~gs_generator.lower_mask; | ||
|
||
gs_generator.MT = malloc(sizeof(*gs_generator.MT) * gs_generator.n); | ||
assert(NULL != gs_generator.MT); | ||
|
||
gs_generator.index = gs_generator.n; | ||
gs_generator.MT[0] = seed; | ||
|
||
for (int i = 1; i < gs_generator.n; ++i) | ||
{ | ||
gs_generator.MT[i] = gs_generator.f * (gs_generator.MT[i - 1] ^ (gs_generator.MT[i - 1] >> (gs_generator.w - 2))) + i; | ||
} | ||
} | ||
|
||
uint64_t rt_random(void) | ||
{ | ||
if (gs_generator.index >= gs_generator.n) | ||
{ | ||
if (gs_generator.index > gs_generator.n) | ||
{ | ||
rt_random_seed(RT_RANDOM_DEFAULT_SEED); | ||
} | ||
|
||
twist(&gs_generator); | ||
} | ||
|
||
uint64_t y = gs_generator.MT[gs_generator.index++]; | ||
y ^= (y >> gs_generator.u) & gs_generator.d; | ||
y ^= (y << gs_generator.s) & gs_generator.b; | ||
y ^= (y << gs_generator.t) & gs_generator.c; | ||
y ^= y >> gs_generator.l; | ||
|
||
return y; | ||
} | ||
|
||
static void twist(struct rt_mt19937_s *gen) | ||
{ | ||
assert(NULL != gen); | ||
|
||
for (int i = 0; i < gen->n; ++i) | ||
{ | ||
uint64_t x = (gen->MT[i] & gen->upper_mask) + (gen->MT[(i + 1) % gen->n] & gen->lower_mask); | ||
uint64_t xA = x >> 1; | ||
|
||
if (x % 2 != 0) | ||
{ | ||
xA ^= gen->a; | ||
} | ||
gen->MT[i] = gen->MT[(i + gen->m) % gen->n] ^ xA; | ||
} | ||
gen->index = 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* Copyright (c) 2021, Evgeniy Morozov | ||
* All rights reserved. | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
#ifndef RAY_TRACING_ONE_WEEK_RT_RANDOM_H | ||
#define RAY_TRACING_ONE_WEEK_RT_RANDOM_H | ||
|
||
#include <stdint.h> | ||
#include <stdlib.h> | ||
#include <limits.h> | ||
#include <math.h> | ||
|
||
#define RT_RANDOM_MAX UINT64_MAX | ||
#define RT_RANDOM_DEFAULT_SEED 5489 | ||
|
||
void rt_random_seed(uint64_t seed); | ||
|
||
uint64_t rt_random(void); | ||
|
||
#endif // RAY_TRACING_ONE_WEEK_RT_RANDOM_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters