Существуют ли поточно-безопасные библиотеки графов для C ++? - PullRequest
5 голосов
/ 21 декабря 2009

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

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

Ответы [ 3 ]

2 голосов
/ 22 декабря 2009

Возможно, вы захотите взглянуть на Parallel Boost Graph Library (и, возможно, Многопоточная библиотека графиков ). Я еще не использовал ни одного из них, просто наткнулся на них, рассматривая параллелизм как вариант ускорения некоторого BGL кода. (Ах ... похоже, что Parallel-BGL теперь официально в надстройке ! Есть хороший обзор архитектуры , но, возможно, их понятие "распределенного графа" довольно грубое по сравнению с тем, что ты имел в виду).

1 голос
/ 22 декабря 2009

К сожалению, стоимость мелкозернистой блокировки, вероятно, выше, чем ускорение от нескольких потоков. Не говоря уже о риске взаимоблокировки, управление блокировками становится ОЧЕНЬ сложнее, когда у вас больше мьютексов, чем очень небольшое.

1 голос
/ 22 декабря 2009

Предполагая, что вы спрашиваете о графиках как о математической сущности (например, о типе графиков, обрабатываемых GraphBase ) - тогда я не думаю, что вы найдете то, что ищете, по крайней мере в библиотеке общего назначения.

Проблема в том, что термин «потокобезопасный» не является четко определенным термином во всех контекстах - как минимум, это, вероятно, означает, что ваша программа, вероятно, не взорвется при одновременной обработке из нескольких потоков - но за ее пределами это требование, даже что-то вроде контейнера или алгоритма, который претендует на то, чтобы быть «безопасным по протекторам», будет иметь некоторую дополнительную семантику относительно того, что именно это означает, - и библиотека графов общего назначения еще более сложна и потребует еще более точного (и настраиваемая) семантика, чтобы удовлетворить это.

Например (здесь речь идет о простом объекте - скажем, контейнере):

Разрешен ли одновременный доступ для чтения к одному и тому же объекту? Разрешен ли одновременный доступ к записи для одного и того же объекта? Читатели блокируют читателей? Читатели блокируют писателей? Писатели блокируют писателей? В целом, какие операции блокируют другие операции?

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

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

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

Другая причина, по которой высокопроизводительные библиотеки можно найти только в поточно-небезопасных версиях, заключается в том, чтобы избежать наказания клиентов, которым эта безопасность не требуется (а может быть, большинство из них для большинства экземпляров данного класса) - при условии, что безопасность потока может быть добавлена ​​извне теми, кто в ней нуждается, но обратное преобразование (удаление безопасности потока) обычно невозможно. Java пошла по этому пути с эффективным отказом от некоторых ранних поточно-безопасных классов, таких как Vector, в пользу ArrayList и StringBuffer против StringBuilder.

С другой стороны, предположение о том, что клиенты могут эффективно добавлять безопасность потоков в контейнеры извне (без доступа к внутренним компонентам), часто неверно - что является основой для потока, созданного из группы Безопасные контейнеры в параллельной упаковке. Однако я очень сомневаюсь, что вы найдете эквивалент для манипулирования графами в C ++.

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

...