6

Wondered if I could get your thoughts on what I should do in this scenario.

Assume I have between 4 to 8 threads and I have a vector of values which will never be written to, only read by the threads.

I have the option of creating a copy of the vector for each thread and then no thread locking between the threads, trying to access a shared copy. Or, I could lock one copy of the vector and make all threads access that.

What is the latency of a thread lock, in comparison to copying the vector? How big would the vector have to be, to make the overhead of the lock faster than copying the vector?

user997112
  • 29,025
  • 43
  • 182
  • 361
  • 3
    Do you really have to lock if it is read only? – juanchopanza May 30 '12 at 21:09
  • 2
    Why would you want a lock if you're only reading data? – user703016 May 30 '12 at 21:09
  • The performance questions are irrelevant to the problem, but if you really want them answered, you'll have to measure yourself. – R. Martinho Fernandes May 30 '12 at 21:11
  • 2
    No need to lock. Just make sure you insert memory fense once data is set up to make sure it goes out of CPU cache. Also, you may want to consider having a copy per NUMA node for better locality if data won't fit in L1/L2 caches. –  May 30 '12 at 21:12
  • @juanchopanza, I was under the impression I have no choice it's done by the threading model? – user997112 May 30 '12 at 21:16
  • 1
    @user997112: That would only happen if you're using a thread-safe vector, as proposed by peekay, which internally takes a lock. But that would kill performance, even if each thread had its own copy. Stick with a lightweight `std::vector` and you'll be fine. – Ben Voigt May 30 '12 at 21:18
  • 3
    @user997112 the choice is completely yours, the question is whether it is necessary to lock. If you are sure all writes to the vector are over before the threads start reading from it, you don't need to do anything else. – juanchopanza May 30 '12 at 21:19

2 Answers2

12

If no thread ever writes to it, you can safely share it without any lock or copy. Data races can only occur if there are write accesses involved.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 9
    @peekay: Adding to a vector is a write. – Ben Voigt May 30 '12 at 21:15
  • Depends what is kept in the vector. If simple data, probably ok, however if struct or classes, you must be sure they don't change their internal state, even if const. That is, that no internal data is mutable, (if struct/class is not thread safe of course) – Niki Jan 23 '17 at 11:03
  • By the way here is interesting thread where the issues is discussed in more details [basic links](http://stackoverflow.com/questions/7455982/is-stl-vector-concurrent-read-thread-safe) – Niki Jan 23 '17 at 11:10
7

Assuming the vector doesn't change after the threads start accessing it, there is no need to lock it. If the thread that populates the vector finishes populating before the reader threads start reading, you are safe without any further synchronization.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480