-
Notifications
You must be signed in to change notification settings - Fork 357
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
Reduce memory consumption in node creation with many threads #2316
Conversation
@hakonsbm That is an impressive reduction in memory use. It would be interesting to see construction and simulation times for realistic network sizes as well. And could memory consumption be reduced even further using |
@heplesser For connection and simulation the nest-simulator/nestkernel/node_manager.cpp Lines 252 to 261 in d2e4974
Therefore, the connection and simulation times should be unaffected, which a run of hpc_benchmark with a scale of 20 supports. Using |
@hakonsbm Good to know that building and simulation time is not affected. But I think the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks generally good, just a few comments/questions.
nestkernel/model.h
Outdated
* Initialize the pool allocator with the Node specific values. | ||
*/ | ||
virtual void init_memory_( sli::pool& ) = 0; | ||
|
||
/** | ||
* Allocate a new object at the specified memory position. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is outdated.
@@ -250,22 +232,17 @@ class Model | |||
/** | |||
* Memory for all nodes sorted by threads. | |||
*/ | |||
std::vector< sli::pool > memory_; | |||
std::vector< std::vector< Node* > > memory_; | |||
}; | |||
|
|||
|
|||
inline Node* | |||
Model::allocate( thread t ) | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are allocate()
and allocate_()
actually good names? Wouldn't create
or clone
be more readable?
|
||
#pragma omp parallel | ||
{ | ||
const index t = kernel().vp_manager.get_thread_id(); | ||
|
||
try | ||
{ | ||
model.reserve_additional( t, max_new_per_thread ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it make sense to keep reserve_additional
to avoid unnecessary automatic vector resizings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with the changes here. Many thanks!
More fundamentally, I'm wondering if we wouldn't be better of with simple thread-local vectors of nodes of a certain type in the GenericModel
instead of packing them into custom pool-based allocators that have never been really tested or designed for performance... But that's probably for another time.
Co-authored-by: Jochen Martin Eppler <jougs@gmx.net>
Creating nodes of different models while using many threads uses an excessive amount of memory. For example, creating 10 populations of 5000 nodes each and different models for each population:
This is because node creation relies on memory management with
sli::pool
:nest-simulator/nestkernel/model.h
Line 253 in d2e4974
By replacing the
sli::pool
with anstd::vector
, the memory consumption is kept at a more manageable level: