Перейти к содержанию
    

Объекты синхронизации в Windows NT

Проблема такая -- пишу WDM драйвер PCI устройства. Отложенная процедура обработчика прерывания (DPC) устанавливает объект событие в сигнальное состояние и начинает выполняться код в режиме пользователя. Суммарная задержка между началом работы ISR и кодом пользователя составляет примерно 350 мкс на Athlon 750.

 

Кто нибудь знает какую часть времени времени занимает выполнение функции синхронизации? :) Насколько я знаю объекты синхронизации ядра выполняются в NT ОЧЕНЬ долго.

 

ЗЫ. Просто вся литература у меня дома, посмотреть ответ смогу вечером только..

 

PPS. Похоже придется использовать QNX, сосвем не нравится замедление работы приложения при перемещении мышки или запуске программ :blink: (приложение запущено с приоритетом реального времени :rolleyes: )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто нибудь знает какую часть времени времени занимает выполнение функции синхронизации? :) Насколько я знаю объекты синхронизации ядра выполняются в NT ОЧЕНЬ долго.

Читал вопрос... Много думал... Ничего не понял ;)

ИМХО, идеология обработки прерываний в NT такая:

1. Происходит прерывание, вызывается процедура, которая была вписана в вызов IoConnectInterrupt(). Процедура выполняется с указанным же при инициализации приоритетом IRQL - при этом обычно может быть вытеснена только другой процедурой прерывания с еще более высоким приоритетом.

2. В этой нашей процедуре делаем все что надо сделать очень быстро в RT, и потом запрашиваем DPC для дальнейшей неспешной обработки.

3. Наша затребованная процедура DPC отработает не немедленно, а ставится в очередь (у каждого процессора в системе своя отдельная очередь DPC)

4. Происходит реальный возврат из прерывания и вот только тогда приоритет упадет до DPC_LEVEL, начнет проверяться очередь DPC и исполняться наша процедура (в порядке очереди).

5. В обработчике DPC можно выставить событие или другой синхрообъект, чтобы поработал пользовательский поток.

6. Заканчивается обработка оставшихся элементов в очереди DPC.

7. Производится переключение контекста на процесс нужного потока (поток до прерывания спал, не факт, что был активен нужный процесс).

 

Так что, собственно объекты синхронизации тут тормозов немного добавляют, ИМО.

Если хотите улучшить временнЫе характеристики свой программы - спускайтесь в ядро, заводите рабочий поток и делайте нужную часть в нем (желательно на PASSIVE_LEVEL), для переключения при освобождении синхронизации можно использовать флажок boost (чтобы пнуть диспетчер, тогда требуемый поток будет первым в очереди на исполнение). Перенос в ядро позволит избежать задержек по пункту 7. Ну и объекты ядра намного быстрее чем производные от них объекты Win32.

Если хочется еще быстрее - можно перенести код в DPC или ISR процедуры - но если работы много и надолго, то Вы реально отравите жизнь всем остальным в системе, так что этот путь нежелателен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто нибудь знает какую часть времени времени занимает выполнение функции синхронизации? :) Насколько я знаю объекты синхронизации ядра выполняются в NT ОЧЕНЬ долго.

Читал вопрос... Много думал... Ничего не понял ;)

ИМХО, идеология обработки прерываний в NT такая:

1. Происходит прерывание, вызывается процедура, которая была вписана в вызов IoConnectInterrupt(). Процедура выполняется с указанным же при инициализации приоритетом IRQL - при этом обычно может быть вытеснена только другой процедурой прерывания с еще более высоким приоритетом.

2. В этой нашей процедуре делаем все что надо сделать очень быстро в RT, и потом запрашиваем DPC для дальнейшей неспешной обработки.

3. Наша затребованная процедура DPC отработает не немедленно, а ставится в очередь (у каждого процессора в системе своя отдельная очередь DPC)

4. Происходит реальный возврат из прерывания и вот только тогда приоритет упадет до DPC_LEVEL, начнет проверяться очередь DPC и исполняться наша процедура (в порядке очереди).

5. В обработчике DPC можно выставить событие или другой синхрообъект, чтобы поработал пользовательский поток.

6. Заканчивается обработка оставшихся элементов в очереди DPC.

7. Производится переключение контекста на процесс нужного потока (поток до прерывания спал, не факт, что был активен нужный процесс).

 

Так что, собственно объекты синхронизации тут тормозов немного добавляют, ИМО.

Если хотите улучшить временнЫе характеристики свой программы - спускайтесь в ядро, заводите рабочий поток и делайте нужную часть в нем (желательно на PASSIVE_LEVEL), для переключения при освобождении синхронизации можно использовать флажок boost (чтобы пнуть диспетчер, тогда требуемый поток будет первым в очереди на исполнение). Перенос в ядро позволит избежать задержек по пункту 7. Ну и объекты ядра намного быстрее чем производные от них объекты Win32.

Если хочется еще быстрее - можно перенести код в DPC или ISR процедуры - но если работы много и надолго, то Вы реально отравите жизнь всем остальным в системе, так что этот путь нежелателен.

 

Смысл моего вопроса заключался в том чтобы узнать какое время (относительно общего времение в 350 мкс) проходит между KeSetEvent и WaitForSingleObject :).

 

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

 

Если можно, напишите чуть подробнее про boost -- где его искать в DDK и с чем его едят :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно что не доступна правка своего сообщения...

 

Я хотел добавить, может интересно кому, переход из режима пользователя (DeviceIoControl) в режим ядра (обработчик DeviceIoControl) составляет на данной машине порядка 20-25 мкс. И еще наврал немного со 350 мкс, более точное значение 100 мкс :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А Вы не могли бы подробнее описать задачу. Какие задержки допустимы и почему именно между KeSetEvent и WaitForSingleObject?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А Вы не могли бы подробнее описать задачу. Какие задержки допустимы и почему именно между KeSetEvent и WaitForSingleObject?

 

Пожалуйста :) Упрощенно схема выглядит так: есть некое устройство под названием КАМАК, к нему подключена моя PCI плата. КАМАК может выставить прерывание, которое прередается на шину PCI. Функцию KeSetEvent вызывает DPC от первичного обработчика прерывания, пользовательское приложение ждет события (WaitForSingleObject) и обрабатывает прерывание (например что-то читает из модуля АЦП КАМАКа). В принципе уже достиг сегодня минимальной скорости реакции (100 мкс). Дальше наверно буду переносить код пользователя в драйвер....

 

А задежки - чем меньше тем лучше :). В принципе 100 мкс уже пойдет, осталось блочную передачу данных между КАМАК и PCI платой в драйвере сделать, тогда задержек таких не будет :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...