альтернатива блокировке / разблокировке мьютекса при доступе к данным класса - PullRequest
0 голосов
/ 09 июня 2011

Я пытаюсь сделать my_class потоко-безопасным, как это.

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() и get_data() могут вызываться разными потоками openmp, поэтому я ввел блокировку.(Поскольку я использую openmp, m_mutex и lock являются обертками RAII вокруг команд omp_init_lock(); и т. Д.).

Однако создание и уничтожение блокировки на get_data () обходится дорого (самая дорогая операция, когда я профилирую свой код - я часто вызываю get_data()).

Можно ли реорганизовать my_class для удаления блокировки в get_data()? Или это блокировка неизбежная стоимость распараллеливания кода?

Ответы [ 2 ]

3 голосов
/ 09 июня 2011

Первым шагом было бы изучить блокировки чтения-записи: таким образом, несколько считывателей не будут блокировать друг друга.

Следующим шагом будет использование операций без блокировки или без ожидания. Есть много ресурсов онлайн, описывающих их лучше, чем я смог бы. Одно замечание: подходы без блокировок имеют дело с атомарными (блокированными) операциями, что означает, что размер данных должен быть небольшим. Если вы пойдете по этому пути, вы будете атомарно заменять указатель на ваш вектор, а не на весь вектор. Это означает, что ваш класс станет немного сложнее и будет иметь дело с некоторыми указателями и управлением памятью.

0 голосов
/ 09 июня 2011

Может быть дешевле использовать критическую секцию вокруг функций get_data / run, вы не будете подвергаться дополнительным накладным расходам на установку / демонтаж (так как критическая секция статически инициализируется), но это также синхронизирует другие экземпляры класса.

...