Re[12]: Реализация критической секции на Interlocked.Exchang
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.06.08 08:57
Оценка:
Здравствуйте, vdimas, Вы писали:

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

N>>Желательно также отработать барьер и после этого — чтобы не тянуть с записью нуля в ячейку спинлока, задерживая тем самым других.
V>Вот тут действительно, стоит поэкспериментировать, что быстрее, один Interlocked.Exchange, или пара барьеров памяти.
V>(Хотя второй опциональный, ИМХО, по крайней мере, когда речь идет об однопроцессорной машине).

На однопроцессорной вообще ни один барьер не нужен. А реализация Interlocked.Exchange может и содержать барьеры (тут уже зависит от стиля). Я бы разделил её на две операции — с барьерами и без. С барьерами — удобно для простых случаев.
The God is real, unless declared integer.
Re[2]: Реализация критической секции на Interlocked.Exchange
От: Sergey Россия  
Дата: 17.06.08 12:20
Оценка:
Сергей Юрьевич Губанов пишет:

> Я тут, вобщем, написал тестовую програмку и запустил её на ночь. Сейчас

> пришёл на работу, смотрю -- работает. Она всю ночь совершала по 2
> миллиона блокировок в секунду и не зависла. Машина двухядерная:
> Athlon-64 X2.

Это вполне подходящий для тестирования процессор, он умеет
переупорядочивать инструкции.

> Это конечно ещё ничего не доказывает, но на размышления

> наводит...
>
> Код:
>
> void EnterCriticalSection ()
> {
> while (System.Threading.Interlocked.Exchange(ref this.flag, 1) != 0)
> {
> System.Threading.Thread.Sleep(0);
> }
> }
>
> void ExitCriticalSection ()
> {
> this.flag = 0;
> }

Насколько я понимаю, с таким кодом вероятен простой баг — одна нитка еще
не выйдет из критической секции, вторая — уже войдет. Соответственно,
тест должен иметь хорошую чувствительность именно к этой ситуации.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[3]: Реализация критической секции на Interlocked.Exchange
От: С. Ю. Губанов Россия http://SergeyGubanov.narod.ru/
Дата: 17.06.08 13:13
Оценка:
Здравствуйте, Sergey, Вы писали:

S>Насколько я понимаю, с таким кодом вероятен простой баг — одна нитка еще

S>не выйдет из критической секции, вторая — уже войдет. Соответственно,
S>тест должен иметь хорошую чувствительность именно к этой ситуации.

Не понимаю как такое может быть? Ведь пока флаг равен 1 никто не войдёт, тут 100% гарантии.

Меня беспокоит другое:

1) Пусть на одном процессоре пришло время выполнить инструкцию flag = 0;
2) а абсолютно одновременно с этим на всех остальных процессорах настало время выполнить инструкцию Interlocked.Exchange(ref flag, 1)

так вот, а не может ли такое случится, что ноль флагу не присвоится никогда? То есть секция останется заблокированной навечно??? Эксперименты показывают, что на протяжении нескольких часов работы "сюрпризов" не возникает, т.е. ноль флагу присваивается. Но вдруг "сюрприза" надо ждать не несколько часов, а месяц или год?
Re[4]: Реализация критической секции на Interlocked.Exchange
От: Sergey Россия  
Дата: 17.06.08 13:56
Оценка: 3 (1) +1
С. Ю. Губанов пишет:

> S>Насколько я понимаю, с таким кодом вероятен простой баг — одна нитка еще

> S>не выйдет из критической секции, вторая — уже войдет. Соответственно,
> S>тест должен иметь хорошую чувствительность именно к этой ситуации.
>
> Не понимаю как такое может быть? Ведь пока флаг равен 1 никто не войдёт,
> тут 100% гарантии.

Из-за переупорядочивания инструкций — например, сначала выполнится
последняя flag = 0, потом — предпоследняя что была под секцией. Думаю, в
таком сценарии между ними еще кто-нибудь вклинится может.

> Меня беспокоит другое:

>
> 1) Пусть на одном процессоре пришло время выполнить инструкцию flag = 0;
> 2) а абсолютно одновременно с этим на всех остальных процессорах настало
> время выполнить инструкцию Interlocked.Exchange(ref flag, 1)
>
> так вот, а не может ли такое случится, что ноль флагу не присвоится
> никогда? То есть секция останется заблокированной навечно???

Не вижу, как такое может быть. Хотя, мало ли чего я не вижу.

> Эксперименты показывают, что на протяжении нескольких часов работы

> "сюрпризов" не возникает, т.е. ноль флагу присваивается.

Эксперименты (как и вообще любые тесты) полной гарантии дать не могут,
но для выявления проблем все равно полезны.

> Но вдруг "сюрприза" надо ждать не несколько часов, а месяц или год?


Бывало у меня такое. В одном месте что-нибудь поправишь — не меняя
синхронизацию, вообще посторонний, но исполняющийся параллельно с
интересующим код, в другом месте баг вылезет.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[3]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 12:17
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, merk, Вы писали:


M>>а где тут критическая секция?

M>>критическая секция в обычной трактовке, реализуется в ядре оси просто запретом переключать треды до конца секции. диспетчер тредов имеет функцию — запретить/разрешешить переключение.

N>Во-первых, мне непонятно, почему для Вас это "обычная" трактовка. Насколько я помню нормы 70-х, там "критической секцией" мог называться, например, кусок кода, выполнять который одновременно могло не более одной задачи. (Вроде synchronized методов в Яве, но мьютекс не на объект, а на функцию.)


N>Во-вторых, в MS Windows критической секцией называется неименованный видимый только из одного процесса мьютекс (в отличие от того, что по CreateMutex и может быть доступен нескольким процессам). Название действительно слабоадекватное, но обсуждение в данной ветке шло именно в его пределах.


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

M>>все остальное — ерунда.

N>Угу. Но пытаясь применить несогласованную терминологию, Вы ушли сильно в сторону.


Отвечаю всем троим сразу, что покритиковали мое типо примитивное понимание крит секции.
Настоящая СИСТЕМНАЯ крит секция — это то, что я сказал. Реализуется запретом переключений и переходом треда в монопольный режим. Такая крит секция используется для написания ядра и регулярных обьектов синхронизации — мьютексов, семафоров, флагов и проч лабуды. Поскольку их же нужно как-то реализовать???
Пользовательская критсекция, о которой говорите вы, есть скрытый мьютекс, семафор или что-то вроде, что как раз и позволяет одному треду захватить этот скрытый мьютекс, а другому , если он занят, встать в ожидание.
фишки вроде, это некий псевдокод
Critical.enter();
...
Critical.leave();
однозначно транслируются в
hidden_mutex.lock();
...
hidden_mutex.unlock().
поскольку базовым обьектом синхронизации является mutex.
Предупреждаю. я использую mutex как термин. Это обьект через который можно осуществить исключительный доступ к участку кода. В некоторых системах его называют семафором, или еще чем. это неважно.
В приведенном автором коде просто написан некий кусок, где непрерываемым образом какая-то переменная взводится. причем тут крит секция, если в ней нет никакого мьютекса или еще чего. на чем встанет в ожидание тред конкурент? или код просто не дописан?
Re[2]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 12:29
Оценка: -1
Здравствуйте, Сергей Юрьевич Губанов, Вы писали:

СЮГ>Я тут, вобщем, написал тестовую програмку и запустил её на ночь. Сейчас пришёл на работу, смотрю -- работает. Она всю ночь совершала по 2 миллиона блокировок в секунду и не зависла. Машина двухядерная: Athlon-64 X2. Это конечно ещё ничего не доказывает, но на размышления наводит...


СЮГ>Код:

СЮГ>
СЮГ>void EnterCriticalSection ()
СЮГ>{
СЮГ>    while (System.Threading.Interlocked.Exchange(ref this.flag, 1) != 0)
СЮГ>    {
СЮГ>        System.Threading.Thread.Sleep(0);
СЮГ>    }
СЮГ>}

СЮГ>void ExitCriticalSection ()
СЮГ>{
СЮГ>    this.flag = 0;
СЮГ>}
СЮГ>


это не критсекция, это гуано. хотя и работает как крит секция.
у вас тред пытающийся войти в занятую вашу секцию, крутится цикле пока не получит доступа в нее. Бесмысленно тратя ресурсы вашей системы, хотя бы вычислительные.
Это же пошло!
По настоящему тред не могущий войти в охраняемый участок сходит с диспетчера в очередь ожидающих данного оьекта. а код выхода из критсекции реализован так, что выталкивает первый ожидающий, или даже все ожидающие входа в данную крит секцию, опять в список активных тредов, то есть на них идет переключение задач.
то есть при нормальном подходе на сленге обчного программиста, если тред в секцию не пускают — он засыпает, пока не получит "сигнал" секция освободилась.
попытка написать эту функциональность обычным прикладным способом, скорее всего приведет к излишним наворотам. поскольку в ядре есть более специальные функции и там это пишетса в пару строк.
не нужно пытаться обмануть и превзойти разработчиков ядра оси. даже если вы уменее, у них больше больше возможностей.
Re[3]: Реализация критической секции на Interlocked.Exchange
От: nikov США http://www.linkedin.com/in/nikov
Дата: 18.06.08 13:15
Оценка: 3 (1) +1
Здравствуйте, merk, Вы писали:

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

M>Это же пошло!
M>По настоящему тред не могущий войти в охраняемый участок сходит с диспетчера в очередь ожидающих данного оьекта.

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

Spinlock
Re[3]: Реализация критической секции на Interlocked.Exchange
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 18.06.08 13:36
Оценка: 3 (1) +2
Здравствуйте, merk, Вы писали:

M>это не критсекция, это гуано. хотя и работает как крит секция.

M>у вас тред пытающийся войти в занятую вашу секцию, крутится цикле пока не получит доступа в нее. Бесмысленно тратя ресурсы вашей системы, хотя бы вычислительные.
M>Это же пошло!
M>По настоящему тред не могущий войти в охраняемый участок сходит с диспетчера в очередь ожидающих данного оьекта.

Вместо того, чтобы ругаться грозными словами — Вы бы почитали чего-нибудь по теме:))

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

Во-вторых, есть ситуации, когда переход в спячку под управлением внешнего шедулера просто недопустим. Их мало, но они есть — например, работа того же шедулера, или истинного обработчика аппаратного прерывания.

M> а код выхода из критсекции реализован так, что выталкивает первый ожидающий, или даже все ожидающие входа в данную крит секцию, опять в список активных тредов, то есть на них идет переключение задач.


Спасибо за разжёвывание азов, век бы без Вас не догадались ;)

M>попытка написать эту функциональность обычным прикладным способом, скорее всего приведет к излишним наворотам. поскольку в ядре есть более специальные функции и там это пишетса в пару строк.

M>не нужно пытаться обмануть и превзойти разработчиков ядра оси. даже если вы уменее, у них больше больше возможностей.

И дороже.
The God is real, unless declared integer.
Re[3]: Реализация критической секции на Interlocked.Exchange
От: CreatorCray  
Дата: 18.06.08 13:37
Оценка: 3 (1) +1
Здравствуйте, merk, Вы писали:

M>это не критсекция, это гуано. хотя и работает как крит секция.

M>у вас тред пытающийся войти в занятую вашу секцию, крутится цикле пока не получит доступа в нее. Бесмысленно тратя ресурсы вашей системы, хотя бы вычислительные.
M>Это же пошло!
Мсье когда нибудь слышал про SpinLock?

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

M>то есть при нормальном подходе на сленге обчного программиста, если тред в секцию не пускают — он засыпает, пока не получит "сигнал" секция освободилась.
Это классический подход, да. Но в случае если занятая секция занимается на небольшое колво тактов поток напрасно продрыхнет квант времени + потратит время на прогулки в ядро для работы с мутексом. Отсюда появились критические секции со спинлоком. На многоядерных/многопроцессорных конфигурациях это дает некоторое ускорение.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[4]: Реализация критической секции на Interlocked.Exchange
От: CreatorCray  
Дата: 18.06.08 13:37
Оценка: +1
Здравствуйте, merk, Вы писали:

M>Настоящая СИСТЕМНАЯ крит секция — это то, что я сказал.

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

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

Мсье не в курсе как работает InterlockedExchange? На фоне заявленного "Большой опыт системного программирования" это выглядит несколько странно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: Реализация критической секции на Interlocked.Exchange
От: С. Ю. Губанов Россия http://SergeyGubanov.narod.ru/
Дата: 18.06.08 13:46
Оценка: 10 (1)
Здравствуйте, merk, Вы писали:

M>это не критсекция, это гуано.


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

Так вот, описанная мной критическая секция используется в случае когда нужно синхронизировать доступ к очень быстро выполняющемуся участку кода. Быстро — это порядка 20 тактов процессора. Примерно столько же тактов нужно для Interlocked.Exchange на Athlon 64 X2. Пример такого быстрого кода: положить/взять чего-то в очередь, в стек или какой-то другой контейнер. Наибольший выигрыш получается когда количество потоков пытающихся сделать это одновременно равно нескольким сотням. Предлагаю Вам сравнить скорость обычного дотнетного lock () с моей критической секцией в Linux Mono хотя бы на одной сотне потоков конкурирующих за вход в неё. Вы будете приятно удивлены огромаднейшей разницей в скорости работы.

M>не нужно пытаться обмануть и превзойти разработчиков ядра оси.


А Вы не допускаете мысли, что я как раз и есть разработчик некоего рантайма? Думаете боги горшки обжигают?
Re[4]: Реализация критической секции на Interlocked.Exchange
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 18.06.08 13:51
Оценка: 13 (2) +1
Здравствуйте, merk, Вы писали:

M>Отвечаю всем троим сразу, что покритиковали мое типо примитивное понимание крит секции.

M>Настоящая СИСТЕМНАЯ крит секция — это то, что я сказал. Реализуется запретом переключений и переходом треда в монопольный режим. Такая крит секция используется для написания ядра и регулярных обьектов синхронизации — мьютексов, семафоров, флагов и проч лабуды. Поскольку их же нужно как-то реализовать???

Спасибо за разъяснение. Но по нему однозначно создаётся впечатление, что Вы учили эту тематику по книгам 20-летней давности (не меньше). А уж утверждение, что есть некоторая "настоящая" критическая секция, а всё остальное, очевидно, ненастоящее — вполне напоминает "я д'Артаньян, а вы все в дерьме". В других местах другие названия, и считать какие-то одни из них настоящими — достаточно смешно.

А теперь про переход в монопольный режим. Во-первых, это наиболее грубый из всех возможных вариантов реализации. Я уже понял, что про wait-free и про lock-free подходы Вы ничего не слышали; тогда почитайте здесь же про них, надеюсь, понравится. Но Вы категорически ограничиваетесь одним процессором! Все Ваши методы типа "запрет переключения" работают только на одном процессоре. Для синхронизации между несколькими процессорами используются другие методы, начиная со спинлоков. В коде, который Вы ругали в следующем письме, приведён именно спинлок. И то, как Вы на него обрушились, свидетельствует именно об устарелости знаний (когда там первые SMP появились?) Особенно это странно сейчас, когда двухъядерный процессор стоит на любом свежем десктопе.

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

M>фишки вроде, это некий псевдокод
M>Critical.enter();
M>...
M>Critical.leave();
M>однозначно транслируются в
M>hidden_mutex.lock();
M>...
M>hidden_mutex.unlock().

Вот в том-то и дело, что не "однозначно", или по крайней мере этот hidden_mutex.lock() делается не как тупой системный вызов. У Sun это названо adaptive mutex, у других — другими именами, но смысл в том, что если interlocked exchange на уровне пользователя даёт захват мьютекса, то этого достаточно, чтобы не просить лишнего от ядра. А по статистике это не менее половины всех захватов (разумеется, в грамотно построенном коде).

В WinAPI, critical section отличается от mutex именно тем, что видима только в одном процессе, но не в другом. Поэтому для неё можно использовать адаптивный захват с ограниченным количеством попыток (а вот если этого недостаточно — оно берёт уже ядерный мьютекс).

M>поскольку базовым обьектом синхронизации является mutex.

M>Предупреждаю. я использую mutex как термин. Это обьект через который можно осуществить исключительный доступ к участку кода. В некоторых системах его называют семафором, или еще чем. это неважно.

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

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


Это спинлок. По-английски — spinlock. Читайте книги (хотя бы википедию), там всё сказано.
The God is real, unless declared integer.
Re[4]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 14:18
Оценка:
Здравствуйте, netch80, Вы писали:

N>Вместо того, чтобы ругаться грозными словами — Вы бы почитали чего-нибудь по теме

и читал по теме..и писал по теме, могу кинуть код ядра реально работающей RTOS.

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

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

N>Во-вторых, есть ситуации, когда переход в спячку под управлением внешнего шедулера просто недопустим. Их мало, но они есть — например, работа того же шедулера, или истинного обработчика аппаратного прерывания.

не спячку, а ожидание. общепринято, что тред переходит в режим wait. ожидание события. коим и является освобождение обьекта синхронизации.
что касается вашего опасения, что это мол долго, то реализуется это очень просто
время тратится на
1. проверка занятости сьютекса(_счетчик >0 && _owner!=CurrentThread)-> перевод обьекта CurrentThread из двухсвязного списка активных тредов шедулера в такой же список ожидающих на этом мьютексе. переключение контекста. ФСЕ! самое длинное — переключение контекста. не хотите переключаться, сидите в полинге. иного не дано. но боюсь в поллинге в рельности вы будете сидеть дольше, чем этот не слишком длинный код. Особняком стоят задачи особой рантаймовости, вроде читки с портов ввода, если там скорость поступления данных сравнима со скоростью их обработки процом. особый случай. можно делать и поллинг.

M>> а код выхода из критсекции реализован так, что выталкивает первый ожидающий, или даже все ожидающие входа в данную крит секцию, опять в список активных тредов, то есть на них идет переключение задач.


N>Спасибо за разжёвывание азов, век бы без Вас не догадались

пожалста.
Re[4]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 14:21
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, merk, Вы писали:


M>>это не критсекция, это гуано. хотя и работает как крит секция.

M>>у вас тред пытающийся войти в занятую вашу секцию, крутится цикле пока не получит доступа в нее. Бесмысленно тратя ресурсы вашей системы, хотя бы вычислительные.
M>>Это же пошло!
CC>Мсье когда нибудь слышал про SpinLock?

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

M>>то есть при нормальном подходе на сленге обчного программиста, если тред в секцию не пускают — он засыпает, пока не получит "сигнал" секция освободилась.
CC>Это классический подход, да. Но в случае если занятая секция занимается на небольшое колво тактов поток напрасно продрыхнет квант времени + потратит время на прогулки в ядро для работы с мутексом. Отсюда появились критические секции со спинлоком. На многоядерных/многопроцессорных конфигурациях это дает некоторое ускорение.

ежли имелась в виду критсекция со спинлоком, то так и надо в стартовом посте писать. Я б назвал этот метод синхронизации — синхронизацией с особым цинизмом. иногда работает. часто очень плохо.
поскольку никто не оговаривает время коотрое тред будет находиться в вашей критсекции(покажите документацию), то намекать что это время мало — несерьезно. ну то есть ваще несерьезно.
Re[4]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 14:23
Оценка:
Здравствуйте, С. Ю. Губанов, Вы писали:

СЮГ>Здравствуйте, merk, Вы писали:


M>>это не критсекция, это гуано.


СЮГ>У меня сейчас есть несколько свободных минут, поэтому я Вам отвечу, хотя Вы этого совершенно не заслуживаете так как Вы чрезвычайно самонадеяны и публично делаете неправильные обобщающие утверждения, а почти ничего не знаете. Вам нужно ещё очень многому научиться.


СЮГ>Так вот, описанная мной критическая секция используется в случае когда нужно синхронизировать доступ к очень быстро выполняющемуся участку кода. Быстро — это порядка 20 тактов процессора. Примерно столько же тактов нужно для Interlocked.Exchange на Athlon 64 X2. Пример такого быстрого кода: положить/взять чего-то в очередь, в стек или какой-то другой контейнер. Наибольший выигрыш получается когда количество потоков пытающихся сделать это одновременно равно нескольким сотням. Предлагаю Вам сравнить скорость обычного дотнетного lock () с моей критической секцией в Linux Mono хотя бы на одной сотне потоков конкурирующих за вход в неё. Вы будете приятно удивлены огромаднейшей разницей в скорости работы.


M>>не нужно пытаться обмануть и превзойти разработчиков ядра оси.


СЮГ>А Вы не допускаете мысли, что я как раз и есть разработчик некоего рантайма? Думаете боги горшки обжигают?
Re[4]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 14:23
Оценка:
Здравствуйте, С. Ю. Губанов, Вы писали:

СЮГ>Здравствуйте, merk, Вы писали:


M>>это не критсекция, это гуано.


СЮГ>У меня сейчас есть несколько свободных минут, поэтому я Вам отвечу, хотя Вы этого совершенно не заслуживаете так как Вы чрезвычайно самонадеяны и публично делаете неправильные обобщающие утверждения, а почти ничего не знаете. Вам нужно ещё очень многому научиться.


СЮГ>Так вот, описанная мной критическая секция используется в случае когда нужно синхронизировать доступ к очень быстро выполняющемуся участку кода. Быстро — это порядка 20 тактов процессора. Примерно столько же тактов нужно для Interlocked.Exchange на Athlon 64 X2. Пример такого быстрого кода: положить/взять чего-то в очередь, в стек или какой-то другой контейнер. Наибольший выигрыш получается когда количество потоков пытающихся сделать это одновременно равно нескольким сотням. Предлагаю Вам сравнить скорость обычного дотнетного lock () с моей критической секцией в Linux Mono хотя бы на одной сотне потоков конкурирующих за вход в неё. Вы будете приятно удивлены огромаднейшей разницей в скорости работы.


M>>не нужно пытаться обмануть и превзойти разработчиков ядра оси.


СЮГ>А Вы не допускаете мысли, что я как раз и есть разработчик некоего рантайма? Думаете боги горшки обжигают?
Re[4]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 14:27
Оценка: -1
Здравствуйте, С. Ю. Губанов, Вы писали:

СЮГ>Здравствуйте, merk, Вы писали:


M>>это не критсекция, это гуано.


СЮГ>У меня сейчас есть несколько свободных минут, поэтому я Вам отвечу, хотя Вы этого совершенно не заслуживаете так как Вы чрезвычайно самонадеяны и публично делаете неправильные обобщающие утверждения, а почти ничего не знаете. Вам нужно ещё очень многому научиться.


СЮГ>Так вот, описанная мной критическая секция используется в случае когда нужно синхронизировать доступ к очень быстро выполняющемуся участку кода. Быстро — это порядка 20 тактов процессора. Примерно столько же тактов нужно для Interlocked.Exchange на Athlon 64 X2. Пример такого быстрого кода: положить/взять чего-то в очередь, в стек или какой-то другой контейнер. Наибольший выигрыш получается когда количество потоков пытающихся сделать это одновременно равно нескольким сотням. Предлагаю Вам сравнить скорость обычного дотнетного lock () с моей критической секцией в Linux Mono хотя бы на одной сотне потоков конкурирующих за вход в неё. Вы будете приятно удивлены огромаднейшей разницей в скорости работы.


M>>не нужно пытаться обмануть и превзойти разработчиков ядра оси.


СЮГ>А Вы не допускаете мысли, что я как раз и есть разработчик некоего рантайма? Думаете боги горшки обжигают?


так бы сразу и сказали. тока меня приучили к мысли, что под критсекцией подразумеватся нечто скорее прикладное, что нужно делать регулярным образом, как я сказал. требовать от прикладного софта особых рантайм харакетристик, ну в обычных задачах — не очень правильно.
Я думал вы радостно ушли в поллинг как простой юзер, ожидая обьект...ну например ожидая когда файл прекратят писать. чтобы его почитать. в таком случае сами понимаете счет идет не на такты проца, а на доли секунды, секунды.
Re[5]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 14:34
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, merk, Вы писали:


M>>Настоящая СИСТЕМНАЯ крит секция — это то, что я сказал.

CC>Мсье может подтвердить сказанное ссылкой на авторитетный проверяемый источник?
CC>Потому как пардон, но я не верю на слово никому, особенно тем, кто претендует на знание "как правильно на самом деле", без соответствующих тому доказательств.

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

CC>Мсье не в курсе как работает InterlockedExchange? На фоне заявленного "Большой опыт системного программирования" это выглядит несколько странно.

не в курсе. какое отношение к программированию имеет конкретная функция из конкретного пакета?
скажите как работает — узнаю.
я думал, по старинке, что она просто обеспечивает непрерываемый обмен двух переменных.
ну..иногда надо, в особо тяжелых случаях.
случай реально — особо тяжелый?
Re[5]: Реализация критической секции на Interlocked.Exchange
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 18.06.08 14:40
Оценка: +2
Здравствуйте, merk, Вы писали:

N>>Вместо того, чтобы ругаться грозными словами — Вы бы почитали чего-нибудь по теме:))

M>и читал по теме..и писал по теме, могу кинуть код ядра реально работающей RTOS.

Тогда Вы слишком странно пишете.

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

M>Большинство блокировок кратковременные — это вы видимо пишете тем, кто реализует мьютексы со сталкиванием с шедулера???

Переведите, пожалуйста, это предложение. При чём тут "сталкивание с шедулера"? Большинство блокировок типа "захватили мьютекс, поменяли два поля, отпустили мьютекс" действительно кратковременные — значительно короче, чем вход в режим ядра.

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


Конечно, не даю. Конечно, как общее решение неприменимо. Но разве автор того кода говорил, что у него единственный допустимый вариант? Чего это Вы вдруг на него обрушились?

N>>Во-вторых, есть ситуации, когда переход в спячку под управлением внешнего шедулера просто недопустим. Их мало, но они есть — например, работа того же шедулера, или истинного обработчика аппаратного прерывания.

M>не спячку, а ожидание.

В данном случае это ожидание — именно спячка;) потому что спинлока тоже ждут, но иначе.

M> общепринято, что тред переходит в режим wait. ожидание события. коим и является освобождение обьекта синхронизации.

M>что касается вашего опасения, что это мол долго, то реализуется это очень просто
M>время тратится на
M>1. проверка занятости сьютекса(_счетчик >0 && _owner!=CurrentThread)-> перевод обьекта CurrentThread из двухсвязного списка активных тредов шедулера в такой же список ожидающих на этом мьютексе. переключение контекста. ФСЕ!

Это Ваше "фсё!" предполагает, что те самые списки шедулера доступны приложению из режима пользователя. Верю, что для RTOS это достаточно частый случай. Но в общем случае я бы такого не предполагал. Например, для той же Windows уход в спячку с ожиданием освобождения мьютекса делается уже средствами ядра — в то время как тред, захвативший объект крит.секции, почему-то:)) тоже спит (мало ли чего он ждёт — может, страница памяти с диска грузится). Полагаться на шедулер и обязательную активность данного процесса некорректно.

M> самое длинное — переключение контекста. не хотите переключаться, сидите в полинге. иного не дано.


Дано, таки дано. Вы слишком узко рассматриваете область возможных применений.

N>>Спасибо за разжёвывание азов, век бы без Вас не догадались ;)

M>пожалста.

Не делайте вид, что Вы не оценили сарказм. Но Ваше чрезмерное тяготение в подходах к одному, совсем не распространённому, типу ситуации (один процессор, слабое разделение прав), который соответствует Вашим письмам — совсем не отражает типичную для многих других картину. И, обрушиваясь на них только потому, что условия не соответствуют Вашим — делаете хуже только себе.
The God is real, unless declared integer.
Re[5]: Реализация критической секции на Interlocked.Exchange
От: merk Россия  
Дата: 18.06.08 14:48
Оценка: :)
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, merk, Вы писали:


M>>Отвечаю всем троим сразу, что покритиковали мое типо примитивное понимание крит секции.

M>>Настоящая СИСТЕМНАЯ крит секция — это то, что я сказал. Реализуется запретом переключений и переходом треда в монопольный режим. Такая крит секция используется для написания ядра и регулярных обьектов синхронизации — мьютексов, семафоров, флагов и проч лабуды. Поскольку их же нужно как-то реализовать???

N>Спасибо за разъяснение. Но по нему однозначно создаётся впечатление, что Вы учили эту тематику по книгам 20-летней давности (не меньше). А уж утверждение, что есть некоторая "настоящая" критическая секция, а всё остальное, очевидно, ненастоящее — вполне напоминает "я д'Артаньян, а вы все в дерьме". В других местах другие названия, и считать какие-то одни из них настоящими — достаточно смешно.


N>А теперь про переход в монопольный режим. Во-первых, это наиболее грубый из всех возможных вариантов реализации. Я уже понял, что про wait-free и про lock-free подходы Вы ничего не слышали; тогда почитайте здесь же про них, надеюсь, понравится. Но Вы категорически ограничиваетесь одним процессором! Все Ваши методы типа "запрет переключения" работают только на одном процессоре. Для синхронизации между несколькими процессорами используются другие методы, начиная со спинлоков. В коде, который Вы ругали в следующем письме, приведён именно спинлок. И то, как Вы на него обрушились, свидетельствует именно об устарелости знаний (когда там первые SMP появились?) Особенно это странно сейчас, когда двухъядерный процессор стоит на любом свежем десктопе.


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

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

M>>фишки вроде, это некий псевдокод
M>>Critical.enter();
M>>...
M>>Critical.leave();
M>>однозначно транслируются в
M>>hidden_mutex.lock();
M>>...
M>>hidden_mutex.unlock().

N>Вот в том-то и дело, что не "однозначно", или по крайней мере этот hidden_mutex.lock() делается не как тупой системный вызов. У Sun это названо adaptive mutex, у других — другими именами, но смысл в том, что если interlocked exchange на уровне пользователя даёт захват мьютекса, то этого достаточно, чтобы не просить лишнего от ядра. А по статистике это не менее половины всех захватов (разумеется, в грамотно построенном коде).


ФСЕ! пошел читать про этот могучий exchange. он уже оказывает и мьютексы захватывает... ладно закопали. думал он просто меняет переменные.
Это в .NET? это спинлок? что это ваще?

N>В WinAPI, critical section отличается от mutex именно тем, что видима только в одном процессе, но не в другом. Поэтому для неё можно использовать адаптивный захват с ограниченным количеством попыток (а вот если этого недостаточно — оно берёт уже ядерный мьютекс).

я так и думал и никакой excahge тут не причем. его отсутсвие позволяет решить проблему не менее принципиально.

M>>поскольку базовым обьектом синхронизации является mutex.

M>>Предупреждаю. я использую mutex как термин. Это обьект через который можно осуществить исключительный доступ к участку кода. В некоторых системах его называют семафором, или еще чем. это неважно.

N>Это важно. Потому что мьютекс — это не просто семафор с не более чем 1 в счётчике. Это семафор, который умеет, в большинстве реализаций, становиться рекурсивным (то есть один и тот же агент может захватывать его много раз), или с контролем ошибок (повторный захват тем же агентом вызывает генерацию ошибки). Для семафора Дейкстры реализация подобных возможностей слишком дорога и неэффективна. Мьютекс оптимизируется в другом направлении, чем семафор с произвольным счётчиком.

а то мы не знали.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.