59482

alternative to mutex lock/unlock when accessing class data

Question:

I am trying to make my_class thread-safe like so.

class my_class { const std::vector<double>& get_data() const { //lock so that cannot get_data() while setting data lock l(m_mutex); return m_data; } void run() { vector<double> tmp; //some calculations on tmp. { //lock so that cannot get_data() while setting m_data lock l(m_mutex); m_data = tmp; //set the data } } private: std::vector<double> m_data; mutex m_mutex; my_class(); //non-copyable }

run() and get_data() may be called by different openmp threads and so I introduce a lock. (Since am using openmp, m_mutex and lock are RAII wrappers around omp_init_lock(); etc. commands).

However, the lock on get_data () is expensive to create and destroy (The most expensive operation when I profile my code - I call get_data() a lot).

<strong>Is is possible to reorganise my_class to remove the lock in get_data()?</strong> Or is this lock the unavoidable cost of parallelising the code?

Answer1:

First step would be to look into read-write locks: this way multiple readers will not block each other.

The next step would be using lock-free or wait-free operations. There are plenty of resources online describing them better than I would be able to. Just one note: lock-free approaches deal with atomic (interlocked) operations, which means the data size needs to be small. If you go this route, you'll be atomically replacing a pointer to your vector, not the whole vector. This means your class will get a bit more complex and will deal with some pointers and memory management.

Answer2:

It may be cheaper to use a critical section around get_data/run functions, you will not incur additional setup/teardown overhead (as the critical section is statically initialized), but this would also synchronize other instances of the class.

Recommend

  • How do I know if a pointer has been assigned data via 'new'?
  • C++ Return value, reference, const reference
  • Value representation of non-trivially copyable types
  • A few memory management questions involving class destructors and delete operator?
  • Why aren't my destructors called when throwing from a win32 timer callback?
  • How to prevent downloading HTML5 videos
  • BASH - Split file into several files based on conditions
  • MS Access 2010 SQL Top N query by group performance issue (continued)
  • Implicit conversion confusion between signed and unsigned when reading K&R book
  • Gnuplot histogram 3d
  • Coalescing items in channel
  • Splitting string into groups of specific length
  • Plot ROC curve and calculate AUC in R at specific cutoff info
  • constexpr vs const vs constexpr const
  • How to create a thread in a class?
  • Grails: how do I set up a response wrapper in a Grails filter?
  • Prevent Emacs from modifying the OS X clipboard?
  • RDF - Distributing rdf:type to all items in the list
  • CFNetwork SSLHandshake failed (-9806) & (-9800) & (-9830)
  • matlab/octave random event ode45
  • How does extglob work with shell parameter expansion?
  • Change URL After Action is Hit MVC?
  • How to sort a same column both in asc order and desc order
  • Recreate the Oracle DUAL table
  • Using SWIG with a build system [closed]
  • How dotnet build chooses the output name
  • Where can I get Microsoft.DirectX.dll?
  • crash in __tcf_0
  • jquery validation - waiting for remote check to complete
  • Can you pass an array from javascript to asp.net mvc controller action without using a form?
  • mave 3.2 not able to access local nexus instance return 502 code
  • Find group of records that match multiple values
  • Security issues with PHP's Readfile method
  • How to Cache Real-time Data?
  • Record samples being played with OpenAL
  • Spray.io: When (not) to use non-blocking route handling?
  • Transpose CSV data with awk (pivot transformation)
  • Getting Messege Twice Using IMvxMessenger
  • How can i traverse a binary tree from right to left in java?
  • How can I use threading to 'tick' a timer to be accessed by other threads?