Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
2465 Discussions

How to destroy objects once placed in ConcurrentVector?

timminn
Beginner
611 Views

The official TBB ConcurrentVector does not provide method to pop up objects?

If we have to free some memory in the middleof runtime process by the destroying the objects placed in the ConcurrentVector, are the objects automatically destroyed when the ConcurrentVector is cleared/destoyed?

If not, how can weobtain the references to the objects placed in the ConcurrentVector? [I was thinking about using some other STL vecter to keep an inventory of the objects, but it seems to be a bad idea: a. the STL one are not concurrent-guaranteed; b. if we can manage the STL one, why do we need the TBB one? c. even if we can handle theSTL one, therewould bedata redundance wasting memory].

0 Kudos
1 Solution
Andrey_Marochko
New Contributor III
611 Views

No, tbb::concurrent_vector does not have erase() method. (Neither it has insert() method.) Its usage model differs from that of a serial vector because insertions to/removals from arbitrary positions cannot be efficiently supported in case of concurrent access.

If it is critical for you, you can destroy item of concurrent vector by storing them as pointers to dynamically allocated objects. Now as soon as it is necessary to free some memory you can delete some objects and set corresponding items to NULL.

But you can safely do this only if you can ensure that other threads do not access items being deleted. And if you can, I wonder if you need concurrent vector at all?

View solution in original post

0 Kudos
4 Replies
Andrey_Marochko
New Contributor III
612 Views

No, tbb::concurrent_vector does not have erase() method. (Neither it has insert() method.) Its usage model differs from that of a serial vector because insertions to/removals from arbitrary positions cannot be efficiently supported in case of concurrent access.

If it is critical for you, you can destroy item of concurrent vector by storing them as pointers to dynamically allocated objects. Now as soon as it is necessary to free some memory you can delete some objects and set corresponding items to NULL.

But you can safely do this only if you can ensure that other threads do not access items being deleted. And if you can, I wonder if you need concurrent vector at all?

0 Kudos
timminn
Beginner
611 Views

No, tbb::concurrent_vector does not have erase() method. (Neither it has insert() method.) Its usage model differs from that of a serial vector because insertions to/removals from arbitrary positions cannot be efficiently supported in case of concurrent access.

If it is critical for you, you can destroy item of concurrent vector by storing them as pointers to dynamically allocated objects. Now as soon as it is necessary to free some memory you can delete some objects and set corresponding items to NULL.

But you can safely do this only if you can ensure that other threads do not access items being deleted. And if you can, I wonder if you need concurrent vector at all?

This is a way. Thank you for your suggestion.

0 Kudos
Dmitry_Vyukov
Valued Contributor I
611 Views

If you have objects that you need to release in the middle of a runtime process to free up some memory, you could allocate them independently of the concurrent_vector but use that concurrent_vector to hold pointers to those objects. Those pointer elements in the concurrent_vector could be smart pointers that keep reference counts on the objects you want to be able to free so that clearing/destroying the concurrent_vector could propagate to freeing up those objects on release of the last pointer.

Note that smart pointer that supports only basic thread safety (like boost::shared_ptr and most other implementations) WON'T work here. One needs smart pointer with STRONG thread safety here. And implementation of smart pointer with strong thread safety is not trivial task in any case. To the best of my knowledge, there is only one lock-free smart pointer that supports strong thread safety out threre. Although such smart pointer can be constructed from normal smart pointer and mutex.

0 Kudos
Dmitry_Vyukov
Valued Contributor I
611 Views
Quoting - timminn

No, tbb::concurrent_vector does not have erase() method. (Neither it has insert() method.) Its usage model differs from that of a serial vector because insertions to/removals from arbitrary positions cannot be efficiently supported in case of concurrent access.

If it is critical for you, you can destroy item of concurrent vector by storing them as pointers to dynamically allocated objects. Now as soon as it is necessary to free some memory you can delete some objects and set corresponding items to NULL.

But you can safely do this only if you can ensure that other threads do not access items being deleted. And if you can, I wonder if you need concurrent vector at all?

This is a way. Thank you for your suggestion.

Note that you can't just zeroize item in vector, you have to employ some form of object lifetime management scheme.

It can be just mutex (possibly reader-writer) associated with every cell in the vector.

Or it can be smart pointer with strong thread-safety (possibly constructed from normal smart pointer + mutex).

Or it can be some form of PDR (Partial Copy-On-Write Deferred Reclamation) - RCU, SMR, ROP, VZOOM, PC etc.

First and second methods are not very good wrt performance and scalability (although it depends on your application).

Third method can provide excellent performance and scalability, basically zero-overhead.

0 Kudos
Reply