На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
Страницы: (3) 1 2 [3]  все  ( Перейти к последнему сообщению )  
> Sleep - что внутри?
    Цитата Jin X @
    А в чём её суть?

    В атомарности.
    Цитата Jin X @
    Temp := Dest
    Dest := Temp

    Ни разу не атомарно.
      Цитата Jin X @
      А вообще, непонятно, зачем cmpxchg делает запись во втором случае. Можно было бы обойтись и без неё.

      Это делается для упрощения "железной логики":
      Цитата Intel
      To simplify the interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the comparison. ... (The processor never produces a locked read without also producing a locked write.)
      А избежать лишних тормозов при вызове cmpxchg в спин-цикле можно программно, добавив перед lock обычное сравнение (как рекомендует интел - “test, test-and-set” technique).
        Цитата shm @
        В атомарности.
        Цитата shm @
        Ни разу не атомарно.
        Иии?
        Я не понимаю, что ты хочешь сказать :)
        Приведённый мной выше код - это внутренняя логика инструкции cmpxchg.

        leo, теперь ясно.
          Цитата Jin X @
          Я не понимаю, что ты хочешь сказать

          То, что именно такая форма инструкции удобна для реализации lock-free алгоритмов и те же примитивов синхронизации.
            shm, ничуть не удобна. Потому что пока она будет делать Temp = Dest и Dest = Accumulator (в случае успешной проверки входа критической секции), то же самое может сделать и другой. И оба войдут в неё.

            Temp1 = Dest
            Temp2 = Dest
            Temp1 = Src ? (Yes)
            Temp2 = Src ? (Yes)
            Dest = Accumulator
            Dest = Accumulator

            Добавлено
            Или мы о разном? :)
              Цитата Jin X @
              Потому что пока она будет делать

              Она это делает атомарно (при наличии lock префикса и для SMP). Ну как еще написать не знаю.

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

              Добавлено
              Я с трудом представляю как без этой инструкции можно реализовать тот же lock-free список. Если у тебя есть идеи - покажи. Кстати эта функция именно в таком виде используется в реализации практически всех примитивов синхронизации.
              Сообщение отредактировано: shm -
                Цитата shm @
                Она это делает атомарно (при наличии lock префикса и для SMP). Ну как еще написать не знаю.
                При наличии lock - естественно. Но ты ж сам написал:
                Цитата shm @
                То, что именно такая форма инструкции удобна для реализации lock-free алгоритмов и те же примитивов синхронизации.
                Если же имелось в виду:
                Цитата
                Неблокирующая синхронизация — подход в параллельном программировании на симметрично-многопроцессорных системах, проповедующий отказ от традиционных примитивов блокировки, таких, как семафоры, мьютексы и события. Разделение доступа между потоками идёт за счёт атомарных операций и специальных, разработанных под конкретную задачу, механизмов блокировки.
                © Википедия
                тогда без вопросов ;)

                Цитата shm @
                Аппаратно эта инструкция, насколько я понимаю, реализована совсем не так, как ты расписал.
                Это код из свежего Intel Instruction Reference (сообщение #27).

                Добавлено
                Цитата shm @
                Кстати эта функция именно в таком виде используется в реализации практически всех примитивов синхронизации.
                Так, а кто ж спорит-то? :)
                  Цитата Jin X @
                  тогда без вопросов

                  именно.
                  Цитата Jin X @
                  Это код из свежего Intel Instruction Reference

                  Это псевдо-код поясняющий поведение инструкции. Он не имеет никакого отношения к ее аппаратной реализации.

                  Добавлено
                  Цитата Jin X @
                  Так, а кто ж спорит-то?

                  А тогда ивзини, я неправильно понял твою реплику про cmpxchg. Тогда leo правильно написал.
                  Сообщение отредактировано: shm -
                    Нашёл интересную вещь в недрах AcquireSRWLockExclusive: NtWaitForKeyedEvent (ntdll.dll).
                    Возможно, это то, что мне нужно (если вернуться к первоначальной теме)...
                    Буду изучать... http://www.locklessinc.com/articles/keyed_events/ :whistle:
                      Jin X, так обычные события чем не угодили я все понять не могу?
                        Уффф... Надо делать Init и Detele (в которых делается Init и Close... ну или просто Delete (Close) (либо создавать и удалять на каждом входе/выходе в/из крит.секции). Они более громоздкие/долгие. Надо делать отдельное событие под каждую критическую секцию (под каждый мьютекс). Короче, этот вариант мне кажется более интересным. Правда, это не совсем то, что я подумал изначально. Изначально мне казалось, что это альтернатива Sleep(1). Но всё равно лучше, чем Event. Вероятно. Я ещё не изучил этот вопрос :)
                          Цитата Jin X @
                          Надо делать Init и Detele

                          Ой да целых пара наносекунд при запуске и завершении твоей программы, ога.
                          Цитата Jin X @
                          либо создавать и удалять на каждом входе/выходе в/из крит.секции

                          Не надо ничего создавать и удалять во время работы. Надо:
                          Enter
                          ...
                          Leve
                          инициализацию и удаления нужно вынести из основного цикла.
                          Цитата Jin X @
                          Надо делать отдельное событие под каждую критическую секцию

                          :wacko:
                          Цитата Jin X @
                          Но всё равно лучше, чем Event

                          Что лучше?
                          Сообщение отредактировано: shm -
                            Цитата Jin X @
                            Нашёл интересную вещь в недрах AcquireSRWLockExclusive: NtWaitForKeyedEvent (ntdll.dll).
                            Возможно, это то, что мне нужно (если вернуться к первоначальной теме)...

                            Во-первых, NtWaitForKeyedEvent работает через тот же event, с той разницей, что 1) к одному эвенту можно прицепить несколько ключей (что несколько замедляет быстродействие, о котором ты так печешься), 2) если вместо первого параметра передать nil\null, то будет использован системный эвент (типа CritSecOutOfMemoryEvent) - возможно это "то, что тебе нужно", если тебе так хочется избежать "лишних" Create\Close, Init\Delete и т.п.
                            Во-вторых, механизм использования NtWaitForKeyedEvent давно встроен в виндовые крит.секции (по кр.мере со времен XP) на случай облома создания собственного эвента крит.секции (по причине OutOfMemory или исчерпания лимита хэндлов). Поэтому, если тебе так нравится изобретать нестандартные велосипеды, то можно использовать небольшой хак с обычной крит.секцией - сразу после InitializeCriticalSectionAndSpinCount(cs,...), установить cs.LockSemaphore:=INVALID_HANDLE_VALUE - и всё, получишь два в одном: и готовый спин-луп с заданным числом повторений и ожидание NtWaitForKeyedEvent на системном эвенте (вместо создания собственного эвента для крит.секции и его ожидания на WaitForSingleObject).
                              leo, интересно... :)
                              Почему же AcquireSRWLockShared, AcquireSRWLockExclusive не используют обычные Event'ы, а работают с KeyedEvent'ами?
                                Цитата Jin X @
                                Почему же AcquireSRWLockShared, AcquireSRWLockExclusive не используют обычные Event'ы, а работают с KeyedEvent'ами?

                                Потому, что это slim - упрощенный "до безобразия" вариант крит.секции. Структура SRWLOCK это набор битовых полей, упакованных в размер указателя (32 или 64 бита). В ней просто нет места не только для указателя на event, но и для OwningThreadID и RecursionCount (со всеми вытекающими особенностями использования по сравнению с крит.секцией). Индивидуального SpinCount-а тоже нет, используется некое дефолтное значение. Соотв-но и для ожидания освобождения лока используется не "обычный", а некий глобальный системный KeyedEvent.

                                PS: Что касается быстродействия поиска ключа, то оно зависит от кол-ва, этих самых ключей, привязанных к одному KeyedEvent-у, ну и от используемой структуры хранения и алгоритма поиска ключей. В XP KeyedEvent использовался только в критической ситуации нехватки памяти, поэтому о быстродействии особо не беспокоились и использовали для хранения ключей простой список. А начиная с висты KeyedEvent-ы стали использовать для SRW-lock, условных переменных и т.п., и соотв-но стали хранить ключи в хэш-таблице для ускорения их поиска. Однако как бы не было реализовано хранение и поиск ключей, при малом\небольшом их кол-ве накладные расходы на их поиск\добавление\удаление составляют незначительный процент от общего времени ожидания эвента на NtWaitForKeyedEvent -> WaitForSingleObject
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) 1 2 [3]  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0442 ]   [ 16 queries used ]   [ Generated: 28.03.24, 21:28 GMT ]