Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Mersenne Twister from C++ standard library #1559

Merged
merged 6 commits into from
Sep 12, 2024
Merged

Conversation

mstimberg
Copy link
Member

When I opened #1483, I did not realize that we have a simple solution – C++11 (not that recent!) comes with PRNGs and it has a Mersenne Twister implementation that is about 6 times as fast as our "radomkit" implementation. So we can delete a lot of code and get faster execution for free 👍

Now, there is one thing that I am not quite sure about: given that we keep using the same algorithm, the quality of the random numbers, the way of how the seed function, multi-threading, etc. works stays the same but you can no longer reproduce the same random numbers simply by setting the same seed, since the implementations for generating the uniform/Gaussian distributions from the raw random numbers differ (and even if they happened to be the same, there are no guarantees how they are implemented).

As an alternative, we can keep our old rk_double and rk_gauss functions around, and just use the new MT generator, which keeps almost all the performance improvement and allows us to exactly reproduce previous numbers. The cost is that the code gets a bit messier, since we still need to ship our own functions – and getting things to work correctly with threads and seeds is slightly more complicated. But maybe worth it? Being able to reproduce the same random numbers as before would be quite nice to guarantee. I think one could say we imply this feature in our docs:

In general, we therefore only guarantee the use of the same numbers if the code generation target and the number of threads (for C++ standalone simulations) is the same.

https://brian2.readthedocs.io/en/stable/introduction/compatibility.html#random-numbers

Closes #1483

@thesamovar
Copy link
Member

6x speed improvement definitely good! I guess reproducibility is probably important for some people, so yeah I would agree with your solution.

@mstimberg
Copy link
Member Author

Yeah, while writing this I convinced myself that this would be good to have ;-) I'll try to refactor a code a bit so that the RNG is a bit more encapsulated than what it is now – this should also make it easier to switch to a different RNG in the future.

@mstimberg mstimberg marked this pull request as ready for review September 11, 2024 10:57
Replace tabs by spaces
@mstimberg
Copy link
Member Author

mstimberg commented Sep 12, 2024

This now looks good from my side, and it reproduces the same random numbers as before. When we generate randn and rand numbers, the speed improvement is less spectacular than by looking only at the random bit generation, but a simple example like this:

G = NeuronGroup(10000, """x : 1
                          y : 1""")
G.run_regularly('x = rand()', name="rand")
G.run_regularly('y = randn()', name="randn")
P = PoissonGroup(10000, rates=10*Hz, name='poisson')

still goes from

randn_codeobject                        3.26 s    52.15 %
poisson_spike_thresholder_codeobject    1.51 s    24.20 %
rand_codeobject                         1.48 s    23.65 %

to

randn_codeobject                        1.18 s    63.96 %
poisson_spike_thresholder_codeobject    0.35 s    18.76 %
rand_codeobject                         0.32 s    17.29 %

i.e. randn() is about twice as fast, and rand() and PoissonGroup (which is using rand() every time step) are about five times as fast.

Copy link
Member

@thesamovar thesamovar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me!

@mstimberg mstimberg merged commit 8f0214d into master Sep 12, 2024
62 checks passed
@mstimberg mstimberg deleted the random_stdlib branch September 12, 2024 16:21
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.

Random number generation on C++ standalone is slow
2 participants