1

I have a multi-threaded c++ program that performs some intensive on-going calculations.

I want the program to write the progress to the GUI/console as the calculation progresses.

To do so I have the threads set some data regarding their individual progress, which the main thread periodically checks in order to determine how much of the total calculation has been completed.

Each thread is assigned a separate piece of data to write to (i.e. element of a std::vector) so no two pieces of data have more than one thread writing to them.

However the main thread must also read these data and thus concurrency is an issue. If two threads access the same data and at least one is a write operation that can lead to a data race which is undefined behavior.

Currently I am preventing this with a single mutex, but I am concerned that this is slowing my program down unnecessarily.

Which makes me wonder - the value of the concurrently used data is not critical to the program logic - so could I, in principle, remove the data race protections (the mutex) - allow data races to happen - and simply manually check to see if the written values are garbage before doing anything with them? Or does the very nature of a data race existing cause wider undefined behavior that could break my problem?

Or is there another, better way, of doing this? Off the top of my head another option would be a vector of atomics such that at least each thread has a distinct concurrency protection so that they are not treading on each other, so to speak.

user3353819
  • 911
  • 2
  • 8
  • 21
  • atomic is the easy way to protect. as long as you aren't checking this progress indicator too often, you should be fine going that route. Mutex is definitely overkill if cpu can handle the update indicator as atomic. Rather than just vectoring atomics, I might consider putting the atomic in a struct and vectoring that to let the compiler pad it. – Abel Sep 26 '21 at 12:41
  • You still have to consider, that even reading data might consist of multiple machine operations, which should not be interrupted in order to avoid half baked results. Some synchronization mechanism is necessary. – πάντα ῥεῖ Sep 26 '21 at 12:45
  • And also worry that the optimiser does not go - well nothing on this thread has updated the (shared) data so we don't need to read it again on this thread. So the updated data does not get read. – Richard Critten Sep 26 '21 at 13:02
  • The behavior is undefined. You can guess at what will happen if you like. It might do what you want. Of course, it will fail when you demo your code to your most important customer. – Pete Becker Sep 26 '21 at 14:00
  • 1
    If I understand correctly, the workers must pay the cost of a locking mechanism each time they access their data just for GUI feedback? As alternative I'd have them communicate their completion status to the main thread (ex message queue), yes there would be a locking mechanism, but just when sending messages (since it's feedback for a GUI, the frequency is order of magnitudes less than accessing data) – MatG Sep 26 '21 at 15:56

0 Answers0