Skip to content

Conversation

@thomas3494
Copy link
Contributor

I replaced the inherently sequential seed_arr of complexity O(k) with an embarrassingly parallel algorithm of O(k log k) complexity. We should create a seed array of length p (or a small multiple) if we have p processors, so the parallel runtime
O(log(p)) will always be smaller than the sequential time O(p).

I also changed the seed_arr API to take any shape, rather than a number as argument. This way we can hide the ugly reshape workaround in Stdlib.

The function seed_arr(seed) computes [seed, seed + 1 * J, seed + 2 * J, ..., seed + k * J], where J is some large number. We can compute seed + K in constant time, if we have precomputed a magic number for that K. The idea is to compute a table of length 32, that has the magic numbers for 2^(j) * J, j = 0, ..., 31. We can then advance the state k * J times in log_2(k) steps by decomposing k into b_0 * 2^0 + b_1 * 2^1 + ... + b_(log_2(k)) 2^(log_2(k)).

I also push the sage code for computing the magic numbers, with references. This can be used to support other GF(2)-based PRNG's as well. The only math necessary to adjust this code, is the matrix form of the generator, all the ring-theory does not differ between generators.

@sbscholz sbscholz merged commit ece6f84 into SacBase:master Nov 28, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants