Потокобезопасная альтернатива только для чтения vtkUnstructuredGrid-> GetPoint () - PullRequest
0 голосов
/ 25 октября 2019

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

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

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

Я пытался разрезать облака точек на куски, но потом это становится слишком сложным, когда у меня слишком много нитей. Я не могу гарантировать оптимизированное количество баллов для обработки для каждого потока. Кроме того, я выполняю поиск соседей для каждой точки, поэтому разделение облака точек на куски становится еще более сложным, потому что для правильного поиска окрестностей мне нужно иметь перекрытия для каждого чанка.

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

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 25 октября 2019

Я не знаком с VTK или с тем, как он работает.

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

  • Легко : если много операций чтения и мало записей, используйте std::shared_mutex, так как это позволяетчитает одновременно.
  • Умеренный : если потоки работают с разными данными большую часть времени: они обращаются к одному и тому же массиву данных, но в разных местах - тогда вы можете реализовать обработчик, который гарантирует, чтопотоки одновременно работают над отдельными частями данных без пересечений, и если поток просит работать над частью данных, которые в данный момент обрабатываются, то попросите его работать над чем-то другим или ждать.
  • Hard : Существуют методы, которые обеспечивают эффективный параллелизм через std::atomic, используя различные инструкции памяти. Я не слишком знаком с ним, и это определенно не просто, но вы можете найти учебники по нему в интернете. Насколько я знаю, некоторые части таких методов все еще находятся в стадии исследований и разработок, а лучшие практики еще не разработаны.

PS Если имеется много операций чтения /записывает поверх одних и тех же данных ... осознает ли реализация тот факт, что данные совместно используются несколькими потоками? Это даже работает правильно? Возможно, вам придется переписать всю реализацию.

0 голосов
/ 28 октября 2019

Я просто подумал, что выложу решение, потому что на самом деле это была моя глупость. Я понял, что в одной части моего кода я использовал double* vtkDataSet::GetPoint(vtkIdType ptId) версию GetPoint(), которая не является поточно-ориентированной.

Для многопоточного кода следует использовать void vtkDataSet::GetPoint(vtkIdType id,double x[3]).

...