Игаль *    (yigal_s) wrote,
Игаль *   
yigal_s

lock-free or mutex or spin-lock

Вот тут http://ru-programming.livejournal.com/1357645.html поставлен очень правильный вопрос - а почему считается, что lock-free эффективнее (лучше скалируется при росте числа тредов и нагрузки), чем обычная синхронизация с блокировками?

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

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

Ситуация, когда lock-free может быть более эффективна, предполагает, что у нас нет задач, которые могли бы выполняться независимо от захвачиваемого ресурса. Но я не уверен, что этим критерием всё однозначно исчерпывается.

Если мы верим, что в конкретной ситуации обычная блокирующая синхронизация имеет слишком много накладок, а оптимистичная синхронизация lock-free работает лучше, то можно подумать о том, не сделать ли нам блокирующую синхронизацию не на системных мютексах, а на spin-locks. Мы тут же выигрываем все эти времена переключения контекста и обращения к ядру, и, более того, теперь наша "блокировка" на spin-lock будет разбужена ровно "вовремя", что куда лучше, чем то, что происходит на lock-free. Иными словами, складывается впечатление, что если lock-free работает лучше мютекса, то spin-lock будет работать примерно так же хорошо, как и lock-free, а то и лучше. Но это не вполне так в силу следующих факторов. Во-первых, тред, захвативший spin-lock, может быть снят с исполнения, что приведёт к нежелательному простаиванию всей системы. Во-вторых, тред, ожидающий spin-lock может сам уже к этому моменту захватить другой spin-lock, что опять же приведёт к ожиданию других тредов, а то и к каскаду ожиданий, который "положит" всю систему (все эти факторы, кстати, могут быть верны и для обычного мютекса).

В общем и целом, методика оценки производительности систем, использующих мютексы, spin-locks и lock-free в общем случае, когда доступ к ресурсу краток (вероятность конфликта мала), средний или длительный (высокая вероятность конфликта) мне по прежднему не ясна.
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 2 comments