sPyNNaker
sPyNNaker copied to clipboard
Delay resolution changes
An alternative way of handling long delays with short time steps would be to reduce the resolution between delays by some factor. As there are 16 delay slots, this would allow the range of delays over these slots to be adjusted. For example, at 0.1 ms time steps, with a delay to time step scale factor of 2, delays would be in units of 0.2 ms, and so only delays of 0.2, 0.4, 0.6 ... 3.2 ms would be representable.
Note that in the C code, the synaptic word would still contain values between 0 and 15 to indicate which delay slot is to be used, but the delays would then have to be pre-divided when putting them in the synaptic word. The ring buffer front pointer would then move at a slower rate depending on this scale factor e.g. at a scale factor of 2, the pointer would only move once every 2 time steps.
One question would be whether the ring buffer is emptied on every time step - experiments would be needed to determine how this affects simulations (or if it does).
Note that powers of 2 are not required in the scale factor - a countdown can be used instead to avoid this requirement, and the delays will be scaled on the host in any case avoiding the need for this requirement. Thus the maximum delay could be used to determine the delay scale factor.
Experiments would be needed to determine the importance of the delay resolution, but this change is relatively simple, so it can be tried out without too much work. This representation has the advantage that no extension rows (or rowlets) are needed, and that no delay extensions are needed, so it should result in an improvement in the efficiency of the synaptic representation (since delay extensions are not needed), the synaptic transfer (since rows will be longer given the same network), and core usage (since delay extensions are not needed).
Note also that delay scale factors might not even need to be integers. If not, the countdown mechanism would be that the number starts at the scale factor and then is reduced by 1 at each time step. The front pointer is then moved when the countdown is < 1, at which point the scale factor is added again e.g.:
accum delay_scale_factor = <value>;
accum counter = delay_scale_factor;
counter -= 1.0k;
if (counter < 1.0k) {
delay_pointer = (delay_pointer + 1) & DELAY_LENGTH_MASK;
counter += delay_scale_factor;
}