-
Notifications
You must be signed in to change notification settings - Fork 6
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
Support long simulations efficiently #61
Comments
Why not just use a 64bit (un)signed integer for everything time related? It'll go for quite a while without reaching the boundary. Most of the computations involving time are intervals, so sustained precision is more important. |
That's roughly the current solution: use a really big (64-bit) number. Most simulations run for only a few seconds. Thus, we expend space and computation to handle a rare use-case. OTOH, the modulo scheme adds almost no overhead and lets the system handle both use cases. |
From the user's perspective time should look the same, regardless of what scheme is adopted. IE: $t should have arbitrary precision over arbitrary amounts of time, and it should be in units of seconds. |
I mention integers also since their arithmetic has less overhead than floating point (though I'm not sure what the comparison between 32bit float operation and a 64bit integer operation is). They have the additional benefit that they are exact with respect to the chosen timestep, making things less complicated (e.g. no need for modulo boundaries except in the very extreme cases). Agreed that from a user perspective it should look the same. |
For the SpiNNaker I will use integers, as the machine lacks an FPU. On a modern x86, the cost of floating-point math is about the same as integer. BTW, in the modulo scheme, the "epoch" value will be an integer regardless. You can think of it as the top portion of a 64-bit integer that is held in common by all current timestamps. |
This issue applies to the Internal and C backends.
Problem: Using single-precision floats, it is only possible to represent about a million cycles. After that, the step size and the current total time have such a large difference in magnitude that bits are lost when dt is added to t. Current solutions include using double precision or ignoring the problem.
Better solution: Use single-precision for time, but store only modulo 1 second. This allows microsecond-sized timesteps. (Alt: set the modulo range based on smallest timestep expected in a specific sim, multiplied by about 1 million.) When new events are injected which cross the modulo boundary (appear retrograde), stash them in a new queue until the old one empties. Increments a counter every time the boundary is crossed, so it is possible to infer total time.
The text was updated successfully, but these errors were encountered: