diff --git a/src/model.hpp b/src/model.hpp index 9862eeee59bc95811d08646a361945392bcc3214..84dd84298a78418ce882b68a29f2211a6e50401b 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -84,9 +84,15 @@ public: } time_type run(time_type tfinal, time_type dt) { - time_type min_delay = communicator_.min_delay()/2; + // Calculate the size of the largest possible time integration interval + // before communication of spikes is required. + // If spike exchange and cell update are serialized, this is the + // minimum delay of the network, however we use half this period + // to overlap communication and computation. + time_type t_interval = communicator_.min_delay()/2; + while (t_<tfinal) { - auto tuntil = std::min(t_+min_delay, tfinal); + auto tuntil = std::min(t_+t_interval, tfinal); event_queues_.exchange(); local_spikes_.exchange(); diff --git a/src/util/double_buffer.hpp b/src/util/double_buffer.hpp index 34dceb7f834768dd4fe768fee03f2ca83f24a7aa..31cffa1babef2ced0b843b4d3e375678612528b2 100644 --- a/src/util/double_buffer.hpp +++ b/src/util/double_buffer.hpp @@ -9,6 +9,7 @@ namespace nest { namespace mc { namespace util { +/// double buffer with thread safe exchange/flip operation. template <typename T> class double_buffer { private: @@ -26,27 +27,35 @@ public: index_(0) {} + /// remove the copy and move constructors which won't work with std::atomic double_buffer(double_buffer&&) = delete; double_buffer(const double_buffer&) = delete; double_buffer& operator=(const double_buffer&) = delete; double_buffer& operator=(double_buffer&&) = delete; + /// flip the buffers in a thread safe manner + /// n calls to exchange will always result in n flips void exchange() { + // use operator^= which is overloaded by std::atomic<> index_ ^= 1; } + /// get the current/front buffer value_type& get() { return buffers_[index_]; } + /// get the current/front buffer const value_type& get() const { return buffers_[index_]; } + /// get the back buffer value_type& other() { return buffers_[other_index()]; } + /// get the back buffer const value_type& other() const { return buffers_[other_index()]; }