18

Lets say I have a vector of int which I've prefilled with 100 elements with a value of 0.

Then I create 2 threads and tell the first thread to fill elements 0 to 49 with numbers, then tell thread 2 to fill elements 50 to 99 with numbers. Can this be done? Otherwise, what's the best way of achieving this?

Thanks

2
  • In a recent video, Stephan T. Lavavej confirms that this works just fine @ 39:12 :) Commented Jun 1, 2010 at 17:50
  • Well I implemented it and it was 4x as fast on my quad and 2x on my duo so it wasn't slow Commented Jun 1, 2010 at 19:13

9 Answers 9

12

Yes, this should be fine. As long as you can guarantee that different threads won't modify the same memory location, there's no problem.

Sign up to request clarification or add additional context in comments.

3 Comments

I think this should actually read "...as long as you guarantee that no thread modifies a memory location that another thread accesses, be it reading or writing access."
It should be noted that even though it should work, it will most likely be very slow due to mutual cache invalidation.
what about multiple thread's trying to read same memory location of vector? hope thats fine?
7

Yes, for most implementations of vector, this should be ok to do. That said, this will have very poor performance on most systems, unless you have a very large number of elements and you are accessing elements that are far apart from each other so that they don't live on the same cache line... otherwise, on many systems, the two threads will invalidate each other's caches back-and-forth (if you are frequently reading/writing to those elements), leading to lots of cache misses in both threads.

2 Comments

I believe that the Windows/Linux implementation of threads does not invalidate cache, since different threads are working on the same virtual memory, unlike different processes.
@Oak, this has nothing to do with the OS. This is implemented by the processor cache. On a system such as x86 with coherent cache, writing to a memory address that has been cached by multiple cores will require an issuing of a read-exclusive (invalidation) operation in order to maintain cache coherence.
4

Since C++11:

Different elements in the same container can be modified concurrently by different threads, except for the elements of std::vector< bool> (for example, a vector of std::future objects can be receiving values from multiple threads).

cppreference discusses the thread safety of containers here in good detail. Link was found in a Quora post.

Comments

2

The fact that "vector is not thread-safe" doesn't mean anything. There's no problem with doing this.

Also you don't have to allocate your vector on heap (as one of the answers suggested). You just have to ensure that the lifetime of your vector covers the lifetime of your threads (more precisely - where those threads access the vector).

And, of course, since you want your both threads to work on the same vector - they must receive it from somewhere by pointer/reference rather than by value.

There's also absolutely no problem to access the same element of the array from within different threads. You should know however that your thread is not the only one that accesses it, and treat it respectively.

In simple words - there's no problem to access an array from within different threads. Accessing the same element from different thread is like accessing a single variable from different thread - same precautions/consequences.

The only situation you have to worry about is when new elements are added, which is impossible in your case.

Comments

1

There is no reason why this cannot be done. But, as soon as you start mixing accesses (both threads accessing the same element) it becomes far more challenging.

Comments

0

vector is not thread safe. You need to guard the vector between threads. In your case it depends on vector implementation. If the vector internal data is accessed\modified from different threads, it purely depends on vector impl.

1 Comment

assuming he's using 'vector' and not a vector (c++/c) - what is the danger in accessing disparate locations?
0

With arrays it can be done for sure (the threads do not access the same memory area); but as already noted, if you use the std::vector class, the result may depend on how it is implemented. Indeed I don't see how the implementation of [] on the vector class can be thread unsafe (provided the threads try to access different "indexes"), but it could be. The solution is: stick to the use of an array, or control the access to the vector using a semaphore or similar.

Comments

-1

What you describe is quite possible, and should word just fine.

Note, however, that the threads will need to work on a std::vector*, i.e. a pointer to the original vector---and you probably should allocate the vector on the heap, rather than the stack. If you pass the vector directly, the copy constructor will be invoked and create a separate copy of the data on each thread.

There are also lots of more subtle ways to get this wrong, as always with multithreaded programming. But in principle what you described will work well.

1 Comment

Why use a pointers to the vector, when std::vector provide iterators. As long as you don't resize the vector, they'll be valid iterators.
-1

This should be fine, but you would end up with poor performance due to false sharing where each thread can potentially invalidate each other's cache line

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.