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

Support long simulations efficiently #61

Open
frothga opened this issue Mar 20, 2018 · 5 comments
Open

Support long simulations efficiently #61

frothga opened this issue Mar 20, 2018 · 5 comments

Comments

@frothga
Copy link
Collaborator

frothga commented Mar 20, 2018

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.

@fywang
Copy link
Contributor

fywang commented Mar 20, 2018

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.

@frothga
Copy link
Collaborator Author

frothga commented Mar 20, 2018

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.

@frothga
Copy link
Collaborator Author

frothga commented Mar 20, 2018

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.

@fywang
Copy link
Contributor

fywang commented Mar 20, 2018

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.

@frothga
Copy link
Collaborator Author

frothga commented Mar 20, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants