Increase mutex array stream

My problem: I have a block matrix updated with multiple threads. Multiple threads may update a non-overlapping block at a time, but overall there may be race conditions. the matrix is ​​now locked using a single lock.

The question is, is it possible (and if so, how?) To implement an effective array of locks, so that only parts of the matrix can be locked at a time.

The matrix in question can be quite large, of the order of 50 ^ 2 blocks. my initial guess is to dynamically highlight a mutex vector / map.

Is this a good approach? Is it better to use several variable conditions? is there a better approach?

thanks

+4
source share
2 answers

Use one lock. But instead of using it to protect the entire matrix, use it to protect std::set (or boost::unordered_set ), which says the blocks are "locked."

Something like that.

 class Block; class Lock_block { public: Lock_block( Block& block ) : m_block(&block) { boost::unique_lock<boost::mutex> lock(s_mutex); while( s_locked.find(m_block) != s_locked.end() ) { s_cond.wait(lock); } bool success = s_locked.insert(m_block).second; assert(success); } ~Lock_block() { boost::lock_guard<boost::mutex> lock(s_mutex); std::size_t removed = s_locked.erase(m_block); assert(removed == 1); s_cond.notify_all(); } private: Block* m_block; static boost::mutex s_mutex; static boost::condition s_cond; static std::set<Block*> s_locked; }; 
+5
source

These can be several approaches that you can use:

  • Define an array if CriticalSection / Mutexes (2500 is not so much) and use a block index as a block index to collect access to the block; before updating the blocks, block all of them that you want to change; update; unlock

  • If the calculation time is much longer than locking / unlocking, then copy the contents of the block in the context of the stream and save the lock during this time; before updating the lock lock again and make sure that it has not been updated by another thread (if that matters); if it was updated by another thread, then repeat the operation;

  • If the size of the contents of the block is small, use atomic data exchange to update the contents of the block, without the need for blocking; just not sure if you are using data from one block to calculate data for another, in this case blocking all the necessary blocks;

  • Is there a read operation on the matrix? If so, use read / write locks to improve performance.

+1
source

Source: https://habr.com/ru/post/1314252/


All Articles