【问题标题】:boost threads mutex array提升线程互斥数组
【发布时间】:2011-03-09 19:56:28
【问题描述】:

我的问题是,我有多个线程更新的块矩阵。 多个线程可能一次更新不相交的块,但通常可能存在竞争条件。现在矩阵是使用单锁锁定的。

问题是,有没有可能(如果有,怎么做?) 实现一个高效的锁数组,这样一次只能锁定矩阵的一部分。

有问题的矩阵可以变得相当大,大约 50^2 个块。我最初的猜测是使用动态分配的互斥体向量/映射。

这是好方法吗? 使用多个条件变量会更好吗? 有更好的方法吗?

【问题讨论】:

  • 您是否总是在程序中处理同一个矩阵?还是矩阵序列(如视频处理)?

标签: c++ performance boost multithreading


【解决方案1】:

使用单个锁。但不是用它来保护整个矩阵,而是用它来保护std::set(或boost::unordered_set),它表示哪些块被“锁定”。

类似的东西。

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;
};

【讨论】:

  • 这确实更简单。谢谢
【解决方案2】:

这可能是您可以使用的几种方法:

  1. 如果CriticalSection/Mutexes(2500没有那么多),则预先分配数组,并使用块索引作为锁索引来收集块访问;在更新块之前锁定您要更改的所有块;做更新;解锁;

  2. 如果计算时间明显长于锁定/解锁,则在线程上下文中复制块的内容并在此期间保持块解锁;在更新块之前再次锁定它并确保它没有被另一个线程更新(如果它与此相关);如果被另一个线程更新,则重复操作;

  3. 如果块内容的大小很小,使用原子数据交换来更新块内容,不需要锁;只是不确定您是否使用来自一个块的数据来计算另一个块的数据,在这种情况下,需要锁定所有更新的块;

  4. 矩阵有读操作吗?如果是,请使用读/写锁来提高性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 2013-01-31
    • 1970-01-01
    相关资源
    最近更新 更多