Re[11]: Performance & Scalability пост №5: приоритеты
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.08.07 20:02
Оценка:
Здравствуйте, Cyberax, Вы писали:

>> Блин. Так потому спинлоки в их стандартном виде и не могут

>> использоваться в среде с насильным preemption в принципе!
C>Так ведь используются (см. EnterCriticalSection) :)

Это не стандартный вид, в котором просто цикл попыток захвата (с модификацией на оптимизацию кэша). Для CRITICAL_SECTION, невозможность получить лок сразу — приводит к вызову уже ядерного ожидания на семафоре CriticalSection->LockSemaphore вызовом NtWaitForSingleObject(). Причём изначально — даже без цикла попыток захвата (может, сейчас оптимизировали? исходники позже NT4 не держал в руках, а лезть отладчиком облом). В терминологии, например, Sun такой объект зовётся "adaptive mutex", и уж никак не "spinlock".

C> В user mode,

C>например, так вообще нельзя никак запретить preemption твоего потока.

В user mode — да. Но тут такими глупостями мало кто занимается. А вот в ядре — сколько угодно. Например, в Linux (образца района 2.4) — spinlock + запрет прерываний (если какой-то обработчик прерывания может лезть к тем же данным) — и достаточно.

А вот для сравнения — FreeBSD SMPng'шная (5-7) — спинлоки использует только для шедулера плюс "нижней" части обработчиков прерываний, только машинно-зависимых действий. Дальнейшая обработка идёт в swi-нитях ядра, у которых задран приоритет, а больше они ничем не отличаются от обычных. И синхронизация там — почти классические мьютексы и местами rwlocks.

C>Ну да, в общем случае они действительно не подходят. А в

C>отдельных частных случаях зато дают огромные преимущества.

Ага. Просто этих отдельных случаев ой как мало...

C>Ээээ... Ты, видимо, не понимаешь сути lock-free.


Зуб даю, начальник, понимаю:)

C> Данные обычно не меняют

C>(это тупо), обычно меняют контейнеры.

Я данными тут называю и всякие указатели в контейнерах. Но ограничиваться контейнерами — таки да, смысла не очень много.

>> При одновременном входе с двух процессоров в случае мьютекса один

>> процессор успеет быстрее другого сделать CAS на объект мьютекса
>> а в случае lock-free — на общие
>> данные, а второй будет или сонно, или решительно, но курить бамбук и
>> уходить на следующий круг.
C>Проблема в том, что со спинлоком он будет курить бамбук все время,
C>пока ты делаешь работу
. В случае с lock-free он будет курить бамбук
C>ровно 1 лишний цикл (если другой претендент ровно в этот же момент не
C>сделает операцию — но это очень маловероятно).

C>Поэтому вместо спинлока в highly contended коде нужно ставить мьютексы,

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

Стоп-стоп. Spinlock vs. mutex — это вопрос не совсем этого самого contented, а скорее вопрос среды, в которой это всё исполняется. На межпроцессорной синхронизации тебе никто мьютекс не даст (слишком дорого делать в железе), там тебе ничего кроме спинлоков не остаётся. Но на такой синхронизации никто и не будет насильно вытеснять (а кто допустил вытеснение — тот просто дурак). А вот спустившись на уровень пользовательских процессов, или даже ядерных процессов, но уже с разрешением вытеснения — наоборот, спинлок становится реальным, но крайне неэффективным. Появляются мьютексы (или в тупой реализации, или поумнее, как с adaptive вариантом), но в любом случае там очередь ожидания и посылание шедулеру сигнала "я сплю, разбуди когда нужно" через соответствующий ядерный запрос.

А lock-free или не lock-free — вопрос именно уровня соревновательности. Если много желающих сделать операцию пришло одновременно — результат получит только один, остальные пойдут на следующий круг. Там тоже один получит результат, остальные будут курить. И так далее... От чрезмерной драки это спасает обычно только недостаточное количество процессоров:) или же максимальное разнесение структур. Если же дофига процессоров и все лезут к одному ресурсу — это получится хуже спинлока.

Кстати, я не понимаю, как обошлись в твоём примере супер-хэша без RCU по отношению к общим структурам хэша.

>> C>Собственно, та hash map масштабируется до 4 тысяч одновременно пишущих и

>> C>читающих процессоров :) Неплохо, ИМХО.
>> Не сказано, как меряли, в плане разнообразия данных. Если там в качестве
>> ключей брались все строки разные — охотно верю. Если бы было много
>> одинаковых — тормозило бы почище чем на локах.
C>Не тормозило бы :)

Уверен? А почему?
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.