Накладные расходы на использование блокировок вместо атомарных встроенных функций

Кто-нибудь знает об опубликованных тестах накладных расходов на блокировку вместо того, чтобы полагаться только на определенно атомарные операции/внутренности (в многопроцессорной системе)?

Меня особенно интересуют общие выводы, т.е. что-то вроде «независимо от платформы, блокировка как минимум в X раз медленнее, чем встроенная». (Вот почему я не могу просто сравнивать себя.)

Меня интересуют прямые сравнения, например. насколько быстрее используется

#pragma omp atomic
++x;

вместо

#pragma omp critical
++x;

(при условии, что каждое второе обновление x также является критическим).

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


person Konrad Rudolph    schedule 28.11.2010    source источник


Ответы (4)


Я не знаю, где есть конкретные исследования, но вы вряд ли где-нибудь найдете окончательный ответ «замки лучше». Это во многом зависит от того, как вы их используете, насколько они подвержены разногласиям и для чего вы используете примитивы. Если все, что вы хотите сделать, это увеличивать числа, то да, вы, вероятно, обнаружите, что атомарные примитивы работают быстрее, чем блокировки, но если вы хотите выполнить сравнение и обмен несколькими словами или сложные обновления древовидных структур и т. д., вам вы обнаружите, что код без блокировок не только намного сложнее и труднее отлаживать, но и что преимущества производительности по сравнению с хорошо спроектированной реализацией на основе блокировок в лучшем случае неубедительны и вряд ли стоят значительного увеличения сложности. ТАНСТАФЛ.

person Marcelo Cantos    schedule 28.11.2010

Меня особенно интересуют общие выводы, т.е. что-то вроде «независимо от платформы, блокировка как минимум в X раз медленнее, чем встроенная».

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

person Huang F. Lei    schedule 28.11.2010
comment
Я должен был быть более конкретным. Предположим, я говорю об обычной современной многоядерной машине с архитектурой x86/ccNUMA. Это что-то меняет? - person Konrad Rudolph; 28.11.2010

MS провела несколько тестов для новых классов параллельных коллекций в .NET 4.

http://blogs.msdn.com/b/pfxteam/archive/2010/04/26/9997562.aspx

Не C/C++, но базовые принципы те же: используйте платформу CAS/связанные операции вместо блокировки там, где это возможно.

У Клиффа Клик также есть несколько эталонных тестов для его хеш-таблицы без блокировок: http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf

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

person Andras Vass    schedule 28.11.2010

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

Итак, старый резервный ответ на вопросы о производительности снова поднимает голову: измерьте оба из них в вашей ситуации и выберите более быстрый.

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

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

person John Doty    schedule 03.12.2010