Параллельная таблица ha sh в C ++ - PullRequest
0 голосов
/ 29 января 2020

В моем приложении в основном есть несколько потоков, которые выполняют вставки, и в основном один поток, который выполняет итерацию по карте и удаляет элементы, если это соответствует определенным критериям. Причина, по которой я хотел использовать параллельную структуру, заключается в том, что она обеспечила бы более точную блокировку зернистости в коде, который удаляет элементы из очереди, что выглядит примерно так, что не идеально по разным причинам, в том числе из-за того, что поток может быть прерван при удержании блокировка.

Function_reap()
{
   while(timetaken != timeoutTime)
   {
      my_map_mutex.lock();

      auto iter = my_unordered_map.begin();
      while(iter != my_unordered_map.end())
      {
        if(status_completed == iter->second.status)
        {
          iter = my_unordered_map.erase(iter);
        }
      }

      my_map_mutex.unlock();
   }
}

Изучал документацию для Intel TBB (Threading Building Blocks) и, в частности, документацию concurrent_unordered_map (https://software.intel.com/en-us/node/506171), чтобы проверить, подходит ли это. для моего приложения и натолкнулся на этот отрывок.

Описание concurrent_unordered_map и concurrent_unordered_multimap поддерживают одновременную вставку и обход, но не одновременное стирание. Интерфейсы не имеют видимой блокировки. Они могут удерживать блокировки внутри, но никогда при вызове пользовательского кода. Они имеют семантику, аналогичную std :: unordered_map и std :: unordered_multimap соответственно, за исключением следующего:

  • Методы стирания и извлечения имеют префикс unsafe_, чтобы указать, что они не безопасны для параллелизма .
  • Почему TBB не обеспечивает безопасное синхронизированное удаление с карты? что является технической причиной для этого?
  • Что если у меня есть какие-либо другие варианты? В идеале то, что определенно работает на Linux и, если возможно, переносимо на windows.

1 Ответ

1 голос
/ 30 января 2020

Что ж, трудно разработать решение, которое (эффективно) поддерживает все операции. TBB имеет concurrent_unordered_map, который поддерживает одновременную вставку, поиск и итерацию, но без стирания, и concurrent_hash_map, которая поддерживает одновременную вставку, поиск и стирание, но без итерации.

Есть несколько других библиотек, которые предоставляют одновременные карты ha sh, такие как libcds, или мою собственную, называемую xenium .

ATM xenium содержит две одновременные карты ha sh реализации:

  • harris_michael_hash_map - полностью без блокировки; поддерживает одновременную вставку, стирание, поиск и итерацию. Тем не менее, количество ковшей должно быть определено во время строительства и не может быть адаптировано впоследствии. Каждый блок содержит связанный список элементов, который не очень удобен для кэша.
  • vyukov_hash_map - это очень быстрая карта ha sh, которая использует мелкозернистую блокировку для вставки, стирания и итерации; операции поиска без блокировки. Однако, если вы используете итераторы, вы должны быть осторожны, чтобы избежать взаимоблокировок (т. Е. Поток не должен пытаться вставить или стереть ключ, удерживая итератор). Однако существует перегрузка стирания, которая требует итерации, поэтому вы можете безопасно удалить элемент, на который указывает итератор.

В настоящее время я работаю над тем, чтобы сделать xenium полностью windows совместимым.

...