Я изучаю различные типы стратегий рекультивации памяти для незакрепленных структур данных в среде, не содержащей мусор (например, C или C++).Восстановление покоя на основе штата и восстановление на основе эпохи
В моих экспериментах, я реализовал несколько из этих стратегий успешно - в частности, как Quiescent государственного Based Рекультивация (QSBR) и Epoch Based Рекультивация (EBR).
Мой вопрос касается одного из ключевых различий между этими двумя стратегиями.
Во-первых, я знаю, как оба QSBR и EBR работы и успешно реализовали оба этих стратегий. QSBR и EBR на самом деле очень похожи. Оба они являются отложенными рекультивациями стратегии - смысл, они избегают условий гонки при освобождении памяти просто deferring фактическое освобождение, пока не будет доказано, что можно освободить память. Как с QSBR, так и с EBR это достигается с помощью глобального «счетчика эпох», а затем для каждого участвующего потока используются различные счетчики тем времени.
Основное отличие между QSBR и EBR заключается в том, что с QSBR вы в основном указываете, когда нить не имеет, имеют какие-либо ссылки на какие-либо общие данные. С помощью EBR вы указываете, когда в потоке есть, есть ссылка на общие данные. Таким образом, на практике, код, который использует EBR заканчивает тем, что больше похож на традиционный замок мьютекса/разблокировать критический раздел, как:
enter_critical_section();
/* do some cool lock-free stuff */
exit_critical_section();
... в то время как, с QSBR, это больше похоже на:
/* do some cool lock-free stuff */
quiescent_state(); // this thread is done using shared data
Таким образом, они очень похожи. Однако одна из ключевых вещей, которые я действительно не понимаю, - это то, как вся литература показывает, что на практике у QSBR есть один главный недостаток: для нее требуется уровень поддержки, что означает, что она не подходит для использования в общей библиотеке.
Это упоминается в многочисленных журнальных статьях или библиотеки документов, таких, как, например, в http://www.cs.toronto.edu/~tomhart/papers/tomhart_thesis.pdf, он говорит:
Тот факт, что QSBR зависит от приложения является фундаментальной разница между QSBR и EBR. EBR по определению обнаруживает изящество периодов на уровне библиотеки. QSBR, напротив, требует, чтобы приложение сообщало о состоянии покоя в библиотеке QSBR. Как мы покажем в разделе 5.2, это дает QSBR значительное преимущество в производительности над
Документов для User-space RCU project, которая использует изменение QSBR, также говорит, что-то подобное:
Однако каждый поток должен периодически вызывать rcu_quiescent_state(), так же, как в ядре, где schedule() необходимо вызывать периодически. Каждый поток, который должен выполнять критические разделы чтения с RCU, должен также вызывать rcu_register_thread() после создания потока и rcu_unregister_thread() перед выходом потока. Эти требования явно ставят строгие ограничения на общую конструкцию приложения, которые, например, для запрещают использование QSBR RCU в большинстве библиотечных кодов, но в return QSBR обеспечивает непревзойденную производительность.
У меня возникли трудности с пониманием, почему это такая проблема. То, что я собираю здесь, это то, что с QSBR приложение должно указывать, когда оно входит в состояние покоя. Но я не понимаю , почему это так сложно сделать на уровне библиотеки?
Невозможно ли блокировать библиотеку, которая предоставляет структуры данных, такие как стеки и очереди, просто указывает, что она вводит состояние покоя после завершения каждой операции? Почему существуют все эти оговорки в отношении QSBR, которые указывают, что это как-то нелегко использовать в библиотечном коде, а не в коде приложения?
Вы можете прочитать http://csng.cs.toronto.edu/publication_files/0000/0159/jpdc07.pdf, и вы увидите «В тривиальном случае, поток может объявить состояние покоя однако после каждой бесконтактной операции, как показано в листинге 1, , часто бывает выгоднее декларировать состояния покоя " – JJ15k