I am computing float
s from multiple threads and storing the results in non-overlapping ranges of the the same vector<float>
as follows:
Before running any of the threads I pre-allocated it using vector::reserve
.
In each thread a thread-specific vector
of results is computed and then copied into the target container like this:
vector<float>::iterator destination = globalVector.begin() + threadSpecificIndex;
std::copy( localVector.begin(), localVector.end(), destination );
Is this a safe practice?
Yes. If the object is accessed (written to) from other threads and you want to copy it, you have to ensure the access is synchronized. Show activity on this post. Thread-safety is only relevant in the context of shared objects.
The C++11 standard does not expect to be able to safely call non const functions simultaneously. Therefore all classes available from the standard, e.g. std::vector<>, can safely be accessed from multiple threads in the same manner.
There is nothing wrong in calling same function from different threads. If you want to ensure that your variables are consistent it is advisable to provide thread synchronization mechanisms to prevent crashes, racearound conditions.
Yes, you are right. I obviously misunderstood that sentence in the documentation: "No contained elements are accessed: concurrently accessing or modifying them is safe." It probably only means that size() is thread-safe against a concurrent modification of the elements already in the container.
First vector::reserve
doesn't actually create any elements. It just sets the the capacity of the vector. If you need the elements to be there you need vector::resize
or just construct the vector to the size needed.
Secondly the rule of thumb is if you have a shared object between threads and at least one of them is a writer you need synchronization. Since in this case the "object" is the iterator range and they do not overlap you are okay in this regard. As long as the vectors size is not changed then you should be okay.
One issue you could have with this is false sharing. If the same cache line contains variables that different threads are using then those cache lines have to re-synchronized every time a variable in the line is updated. This can slow down the performance of the code quite a bit.
If the vector has fixed size (and it seems like it has from your question), and ranges are not overlapping, then:
thus I don't see any data races here. (But according to 1st comment to your question, you must ensure, that vector has this fixed size when it is used). You can see also "Data Races" section for std::copy: http://www.cplusplus.com/reference/algorithm/copy/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With