OberonCore https://forum.oberoncore.ru/ |
|
Реализация критической секции на Interlocked Exchange https://forum.oberoncore.ru/viewtopic.php?f=31&t=1029 |
Страница 1 из 2 |
Автор: | Сергей Губанов [ Понедельник, 16 Июнь, 2008 11:16 ] |
Заголовок сообщения: | Реализация критической секции на Interlocked Exchange |
Вот, ежели я реализую критическую секцию используя атомарную операцию обмена, то MSDN рекомендует писать что-то вроде следующего: Код: if (System.Threading.Interlocked.Exchange(ref flag, 1) == 0) { // ... // ... // ... System.Threading.Interlocked.Exchange(ref flag, 0); } А почему бы не написать попроще: Код: if (System.Threading.Interlocked.Exchange(ref flag, 1) == 0) { // ... // ... // ... flag = 0; } Вроде второй вариант тоже правильный, или нет? |
Автор: | Илья Ермаков [ Понедельник, 16 Июнь, 2008 11:44 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
В данном случае, может быть, и будет работать. А вообще, если во время записи в переменную кто-то ещё может её читать, то надо использовать Interlocked. Может быть (теоретически, относительно тех. возможности конкр. процессоров не знаю) такая ситуация, что один процессор записал только часть слова, а второй уже полез читать. |
Автор: | Wlad [ Понедельник, 16 Июнь, 2008 11:54 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Сергей Губанов писал(а): Вроде второй вариант тоже правильный, или нет? Ёй! Лучше - не надо! - Неизвестно на какой проц, в недалёком и светлом будущем, это потом нативно скомпилено будет... |
Автор: | Wlad [ Понедельник, 16 Июнь, 2008 12:09 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Илья Ермаков писал(а): такая ситуация, что один процессор записал только часть слова, а второй уже полез читать. Не,... с частями слова - наврядли, но вот на счёт такого - вполне "ох-ох-ох": Код: mov eax,0 // или xor eax,eax // здесь уходим в другой поток, потом - продолжаем... mov var,eax В то время, как System.Threading.Interlocked.Exchange(ref flag, 1) скорее всего подразумевает компиляцию в команду, типа xchg на х86 (или её аналог на других архитектурах), которая в любых условиях и архитектурах выполняется гарантированно атомарно... |
Автор: | Сергей Губанов [ Понедельник, 16 Июнь, 2008 12:22 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Спасибо. |
Автор: | Сергей Губанов [ Понедельник, 16 Июнь, 2008 12:45 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Владимир Лось писал(а): Код: mov eax,0 // или xor eax,eax // здесь уходим в другой поток, потом - продолжаем... mov var,eax Не совсем понимаю чем это плохо? Ведь переменной flag всё равно будет присвоен 0, правда не мгновенно, а с небольшой задержкой. |
Автор: | Wlad [ Среда, 18 Июнь, 2008 19:31 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Сергей Губанов писал(а): Владимир Лось писал(а): Код: mov eax,0 // или xor eax,eax // здесь уходим в другой поток, потом - продолжаем... mov var,eax Не совсем понимаю чем это плохо? Ведь переменной flag всё равно будет присвоен 0, правда не мгновенно, а с небольшой задержкой. Как-то не кошет... А если у вас флаг не бинарным будет?... Да ещё и "привязанный" значениями к потокам?... :о) |
Автор: | Trurl [ Четверг, 19 Июнь, 2008 09:50 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Скорее всего flag = 0; будет скомпилировано в Код: mov flag, 0 , а System.Threading.Interlocked.Exchange - в вызов InterlockedExchange.Код: push 0 push flag call InterlockedExchange ... InterlockedExchange: mov ecx, [esp+4] mov eax, [esp+8] xchg eax, [ecx] ret 8 Особой разницы не вижу |
Автор: | Сергей Губанов [ Четверг, 19 Июнь, 2008 12:55 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Я на RSDN спросил: http://www.rsdn.ru/forum/message/2988602.1.aspx там сказали, что может случится так, что слишком интеллектуальный процессор с целью оптимизации может поменять порядок выполнения инструкций и код flag = 0 может оказаться выполненым чуть раньше чем надо, но код с "интерлокедом" процессор с другим кодом менять местами не будет. |
Автор: | Евгений Темиргалеев [ Четверг, 19 Июнь, 2008 13:09 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Короче с этими навороченными CISC процессорами программировать приходится с RISC-ом для себя. Как в Си++ -- множество подводных камней. И не знаешь, как себя будет вести завтра новая модель... |
Автор: | Mirage [ Четверг, 19 Июнь, 2008 16:39 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Может быть изменен порядок не инструкций (хотя и инструкций тоже может) а непосредственно операций чтения и записи. Причем не только самим CPU, но и продвинутым компилятором. Конкретно на x86 - операция чтения может быть помещена CPU перед операцией записи, хотя встречена сперва запись. В рамках одного ядра/процессора обеспечивается верный результат, а вот при многоядерности/многопроцессорности уже нет. Есть понятие такое - барьер (MemoryBarrier в Windows). Через него операции "не проходят". Interlockedxxx уже содержат этот барьер. |
Автор: | Сергей Губанов [ Четверг, 19 Июнь, 2008 17:22 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Mirage писал(а): Конкретно на x86 - операция чтения может быть помещена CPU перед операцией записи, хотя встречена сперва запись. Это хорошо, значит на x86 операция записи flag = 0; выполнится заведомо после фактического выхода из критической секции. Значит можно безбоязнено использовать простую flag = 0; вместо её интерлокед-варианта... Я на работе уже на три ночи оставлял программу работать с простым flag = 0; она всё ещё и не зависла. Машина: Athlon64 X2. |
Автор: | Евгений Темиргалеев [ Четверг, 19 Июнь, 2008 20:25 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Сергей Губанов писал(а): Значит можно безбоязнено использовать простую flag = 0; вместо её интерлокед-варианта... А смысл? Оптимизация?
|
Автор: | Mirage [ Пятница, 20 Июнь, 2008 09:45 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Сергей Губанов писал(а): Это хорошо, значит на x86 операция записи flag = 0; выполнится заведомо после фактического выхода из критической секции. Значит можно безбоязнено использовать простую flag = 0; вместо её интерлокед-варианта... Эт если инструкции из защищенной секции не будут перемещен CPU еще дальше, а он может. Если будут, то секция не будет полностью защищать весь код. Вобщем станут возможны всякие чудеса. И тесты это не выявят, т.к. перемещение инструкций зависит от кода, т.е. тест должен все время менять защищенный код. Если так важна скорость, то может имеет смысл использовать т.н. lockless синхронизацию. В принципе, как раз это и пытаетесь сделать, т.к. Interlockedxxx обычно тут и используются. Но еще есть ассемблерные инструкции типа cmpxchg, через которые interlockedxxx и работают. Но тут надо очень хорошо понимать все эти перемещения инструкций, операций чтения/записи и т.п. и знать когда надо ставить барьеры, а когда не надо. |
Автор: | Сергей Губанов [ Пятница, 20 Июнь, 2008 09:55 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Евгений Темиргалеев писал(а): А смысл? Оптимизация? Да. Если вместо двух interlocked-операций можно использовать только одну, то будет работать почти в два раза быстрее! Операции семейства Interlocked.*** на многопроцессорной машине выполняются тактов примерно от 20-30 и более в зависимости от типа и количества процессоров (20-30 - это не теоретическое значение, а это я типа померил на Athlon 64 X2). Хотя конечно, на однопроцессорной машине при наличии всего одного потока время выполнения может быть небольшим, затрудняюсь сказать сколько, наверное тактов 2-6. Ежели надо защитить участок кода, который сам выполняется тактов за 5-10, то использование спинлока на interlocked-операциях самое то. |
Автор: | Сергей Губанов [ Пятница, 20 Июнь, 2008 09:59 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Mirage писал(а): Эт если инструкции из защищенной секции не будут перемещен CPU еще дальше А если я сделаю присваивание flag = 0 в отдельной процедуре Exit: Код: MySpinlockCriticalSection.Enter; ... a := b; MySpinlockCriticalSection.Exit; неужели процессор на столько может обнаглеть, что выполнит сначала MySpinlockCriticalSection.Exit; а потом a := b? Всё-таки вызов процедуры... |
Автор: | Mirage [ Пятница, 20 Июнь, 2008 10:54 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Сергей Губанов писал(а): неужели процессор на столько может обнаглеть, что выполнит сначала MySpinlockCriticalSection.Exit; а потом a := b? Всё-таки вызов процедуры... Вызов процедуры для CPU это не более чем инструкция call. Её тоже наверное может подвинуть. И те, что "в ней", тоже. Насколько я знаю, call барьером не является. Вот если вызов косвенный, то, опять же если не угадает с предсказанием перехода, то инструкции в процедуре не переместит, т.к. их не будет в конвейере или куда он их там выбирает. |
Автор: | Wlad [ Воскресенье, 22 Июнь, 2008 13:02 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
"...а как всё хорошо начиналось! - вызываем в Москву... и как всё закончилось - на конкурс самодеятельности!..." И вот представьте: это кто понимайт - говорит и обсуждает ( с разумением оп чём ваще речь идёт ), а каково среднестатистическому вчерашнему студенту (да - и не только!)?! : "Фсё зробыв по правилам! - а включашь - фигня получается!" |
Автор: | Vlad [ Воскресенье, 22 Июнь, 2008 22:39 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Владимир Лось писал(а): И вот представьте: это кто понимайт - говорит и обсуждает ( с разумением оп чём ваще речь идёт ), а каково среднестатистическому вчерашнему студенту (да - и не только!)?! : "Фсё зробыв по правилам! - а включашь - фигня получается!" Студент в любой книжке про многопоточную разработку прочитает про примитивы синхронизации. И будет их использовать. А уж если он захочет свой примитив забабахать, то пусть читает про барьеры, особенности процессоров и т.д. P.S. Почему нельзя использовать флажки в виде обычный переменных для синхронизации - в приличных книжках тоже пишут. Потому как это частая ошибка у недоучившихся студентов. |
Автор: | Илья Ермаков [ Понедельник, 23 Июнь, 2008 06:43 ] |
Заголовок сообщения: | Re: Реализация критической секции на Interlocked Exchange |
Так речь не о примитивах синхронизации, а о "соответствии" написанного и сгенерированного кода, которое может получиться... С точки зрения синхронизации первый вариант Сергея вполне верен - если изменение идёт внутри критической секции, значит, его выполняет только один поток. Однако, зная, что всегда тут будут "заподлы", я бы, конечно, так не стал делать, о чём сказал Сергею... А дальше коллеги конкретно объяснили, почему... |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |