Такую тему я поднимал на кл, но потом закрыл там набежала толпа тролья. Так ничего не прояснилось. Замерялось число прерываний в секунду, юзермод через обнуление селекторов(RPL). Это хороший способ, по какой то причине при нагрузке(активность GUI) растёт число прерываний, почему я так и не понял. На скрине число прерываний в секунду для юзер треда. Что подчёркнуто это перемещение окна иного процесса, при этом по какой то причине идёт всплеск по профайлу(теоретически должно быть снижение). Замер в 1 и 16 потоках. resol - разрешение системного таймера(софт механизм не перестраивает железо, NtSetTimerResolution), apic - включен таймер контр. прерываний(NtStartProfile), это более частный вызов планировщика. Есть вероятность что при обработке прерывания идёт серия софтверных, посылкой команд в апик.
Тоже самое. У меня прикол на атоме был. При интенсивном выводе графики сетевуха не успевала отработать отсылку пакетов. При этом нагрузку на неё был минимальная, но количество прерываний было в результате в 10 раз больше. Такое впечатление, что она не успевала по времени что-то сделать поэтому всё дергала и дергала проц. Причём раз подсчёт прерываний идёт это точно не блокировка. (Ну не станет же винда через NMI себя прерывать что-бы рассклинить другое прерывание) или станет? Да и нагрузка на видео не связана с прерыванием там примитивный DAC был софтварный bitblt. iKVM отсутствует так как видео в процессоре нету. Короче моё предположение следующее. Железо кривое при превышении нагрузки на шину между процессором и северным мостом(шина FSB), теряет или как-то искажает подтверждение приема прерывания или неверно сбрасывает источник прерывания. Соответственно проц думает что он обработал прерывание, а железо которое выставило думает что нет. А что-бы проверить надо лезть в ядро и смотреть, что там проверять ошибки контроллеров прерывания и шин. А так же мониторить флаги прерываний в устройствах.
Pavia, > Соответственно проц думает что он обработал прерывание, а железо которое выставило думает что нет. У меня счётчик увеличивается именно при возврате по iret, тоесть прерывание обработано.
Interrupt handler он же ISR он же обработчик прерывания вызывается после iret. Делается это из разных соображений:1. Для отладки. 2. что-бы не терять прерывания. 3. И основное. Для того что-бы получить контекст процесса, запустить system theard. Так как только в потоке вы можете гарантировать когерентность данных. По другому синхронизацию данных вы не сделаете. Даже AtomLock не поможет потому прерывание случаются в произвольный момент и никто не гарантирует что поток(для примера system thead) не находится в состоянии между Read-Operate-Write с переменной с которой нужно синхронизироваться, а у вас к тому же прерывания запрещены поэтому жди не жди а борьер не сбросится. Поэтому их вначале разрешают через iret, а уже потом начинают выполнять ISR. Так проще единственно что надо успеть с высшим приоритетом выполнить ISR. Но после iret вы попадаете в некоторый поток от которого до ISR ещё должно пройти время. Возможно тут и повисает железо. Так вот EOI посылается из ISR к контролёр прерывания. Но по мимо этого EOI нужно отправить ещё и в девайс, который вызвал прерывание в системе. Для примера у контролёра 8042 посылкой EOI считается чтение 60h порта. Но это не явная посылка. Если вы не прочитаете 60h то клава будет висеть. По правилам разработки железа такого не должно быть. Однако по факту криворуких-рукожопов хватает. А вот у других железок явная посылка к примеру для RTL8139 нужно послать 1 в нужный разряд чтоб разрешить нужное прерывание outport(IOBase + ISR, ISR_TOK); Если сетевуха это не получила она будет по таймеру периодически дергать процессор (если он включен). Для жёских дисков. Interrupt — R/WC. Software can use this bit to determine if an IDE device has asserted its interrupt line (IRQ 14 for the Primary channel, and IRQ 15 for Secondary). 0 = Software clears this bit by writing a 1 to it. If this bit is cleared while the interrupt is still active, this bit will remain clear until another assertion edge is detected on the interrupt line.
Pavia, > обработчик прерывания вызывается после iret. Как это, вложенные прерывания, те возврат по iret приводит к другому ? Понятно что iret выполняет теневую" обработку, а не просто передачу управления. Если очередь прерываний не пуста, то наверно iret приведёт к вызову нового вектора. Но это если частота их выше частоты обработки. В моём случае если не запущен апик таймер частота порядка сотни герц, если таскать окна мышем то растёт, на скрине показано. Вероятно при движении мыша идёт серия прерываний, оно повышается также и при замере через частоту их системой(см ниже). В нт немного способов в юзер эту всю инфу получить. Замер прямой в цикле обнулением RPL(при iret), те фактически это число iret/1sec. Так как поток крутится в цикле не вызывая ядерные сервисы, то число iret и есть число прерываний в этом потоке ? Если получить число прерываний на процессоре, а нт это считает(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), то оно оказывается значительно ниже прямого замера в потоке(> 2.5 раза), что так же не понятно(наоборот частота должна быть выше, так как на процессоре прерываются все потоки в системе). Есть пара нюансов, так этот счётчик инкрементируется только из ядра при обработке нескольких ISR, например hal ставит несколько ISR, при этом в них прямо счётчик не трогается, возможно косвенно через обратный вызов ядра при обновлении часиков/планировщик. Второй нюанс что ядро посылает софт запросы на прерывания, IPI/APC/DPC/etc. Как и что измерить я хз, единственный способ наверно это только если всю таблицу IDT пропатчить на заглушки, которые будут индексировать счётчики и посмотреть какой вектор приводит к росту числа возвратов.. Так же не ясно почему нет разницы в частоте прерываний если таймер апик настроен на макс частоту.
В покое у меня 200 прерываний в секунду. В пике 20 000 в секунду. В виндоусе и так есть счётчик. У мыши PS/2 количество прерываний дин омическое от 0 до Max. USB мыши являются PS/2 совместимыми. Число посылок и как следствие прерываний настраивается кодом F3 и ограничено 1 байтом, т.е максимум 255 прерываний. Геймерские мыши исключат совместимость с PS/2 поэтому выдают до 5000 пакетов в секунду. Но тут видимо уже USB оптимизирует количество прерываний. Время обработки любых прерываний врятли превышает 10 мкс. 20 000 * 10 мкс = 200 мс. Т.е. даже в пике у ваш процессор будет загружен только на 20%. Думаю равно. С чего вдруг? Многоядерность у каждого свой лапик(LAPIC). Так что потоки на разных ядрах не прерываются. Для работы планировщика я бы прерывал все ядра(а как в виндоусе я ХЗ). После прихода прерывания ты можешь написать код. Но данные из этого кода можно передать в приложение либо по таймеру, но таймер это медленно. Более быстро через выставления Devices IRQL, или DIRQL в диапазоне от 26 до 3 выполнения IRET возврата http://www.reverse-engineering.info/SystemInformation/understanding_irql.pdf Далее винда разгуливает системный поток. И передает прерывание драйверу с нужным потоком. К стати видимо от сюда и 2-х кратный рост прерываний. Видел такое предположение что легаси код. Либо есть ещё такое предположение. Мне известно что на одной векторе сидит несколько обработчиков. Каждый должен проверить его это прерывание или нет и далее по цепочке отдать. Так вот есть старые драйвера которые не умеют проверять его прерывание или нет. Вот винда разруливает.
Pavia, > Мне известно что на одной векторе сидит несколько обработчиков. Каждый должен проверить его это прерывание или нет и далее по цепочке отдать. Так вот есть старые драйвера которые не умеют проверять его прерывание или нет. Вот винда разруливает. Системные ISR используют общий счётчик. Почему же тогда значение системного счётчика совпадает с замером в потоке, разница не значительна, если даже это на порядок, то я говорил, не все вектора используют системный счётчик. Короче вообще ничего не понятно. > Более быстро через выставления Devices IRQL Хал транслирует виртуальный IRQ в апик, оно так в символах и называется HalpIRQLtoTPR" Есть есчо некая HalRequestSoftwareInterrupt() которая перестраивает апик. > Так что потоки на разных ядрах не прерываются. О чём вы говорите. Прерывается всё и непрерывно, что частотами я не знаю, собственно и спросил. Вопрос сложный, слишком много нюансов. > Геймерские мыши исключат совместимость с PS/2 поэтому выдают до 5000 пакетов в секунду. Но тут видимо уже USB оптимизирует количество прерываний. Мышь непрерывно шлёт пакеты, хотя это вы скажите. Перемещение USB-мышки приводит к прерываниям, те в отличие от посылок если она не движется ?
Для маркетинга чего только не сделают. Но обычно мышь шлёт данные только тогда когда есть что слать. Есть перемещение то шлет. Нет перемещения не шлёт. Я исходники NT4 посмотрел там это для других целей применяют. Но вообще конструкция странная зачем таблица, когда по факту ложное срабатывание. Короче что-бы понять логику ядра win7 надо не годать, а от дизассемблировать. Никогда не делал. Какой программой лучше? Так маны интела почитайте у каждого ядра свой LAPIC прервать можно только меж процессорным сообщением от одного ядра другому или от одного всем ядрам сразу(прим до 16 ядер). Судя по исходникам NT4 там всё просто. Исключения сидят на своих обработчиках прерывания на своих. Пришло прерывание от устройства попало в диспетчер прерываний он из табличке взял объект с нужным векторам и вызвал объект с ISR. Если это шина, т.е на одном векторе несколько устройств то тут уже в цикле диспетчер вызвал 2LV. https://www.codemachine.com/article_interruptdispatching.html https://forum.sources.ru/next/index.php?showtopic=70521&view=showall
Pavia, > у каждого ядра свой LAPIC прервать можно только меж процессорным сообщением На тестах процессорная маска(affinity) не влияет на результат, проверено. Небольшая разница, но это планировочный шум. > Но обычно мышь шлёт данные только тогда когда есть что слать Ты же ведь шаришь в железе, скажи как это работает. Если перемещать мышь без окна I/s растёт не значительно. Но оно растёт при замере числа прерываний на процессор. Что вполне ожидаемо. Но если таскать мышью чужое окно происходит всплеск по частоте Is. В ядре гуя нет даже импорта, связанного с обработкой прерываний.
Незачем гадить в теме, мне интересно понять почему часы бежат и версия системы никакого значения не имеет для разбора. Механизм весьма сложный и интересный. Rel тоже про линь не нужно, вот там именно у вас пукан пригорит" при попытке выяснить баг, тк даже инструментов и в общем средств для разбора толковых нет. R81... > при длительных по времени многократно используемых ClI системное время естественно начинает отставать И вот почему. Часовой счётчик не доступен, те нельзя прочитать миллисек из ртк, он кидает сигнал при переполнении. Поэтому механизм счёта времени на таких длительностях основан на числе прерываний. В хал есть соотв таблица, в которой заданы частота и дельта соотв по таймингу. Когда часы тикают, те идёт прерывание, время увеличивается на опред величину, без чтения часов. По дефолту есть таймер, односек по которому идёт синхрон с часами, но есть всякие разные настройки показанные в той теме. Долго я возился с часами, короче нужно лезть в ядро смотреть что есть в переменных. Сразу возникает вопрос wtf!?: - два массива ключевых переменных, в двух запусках часы откалиброваны макс/мин(NtSetTimerResol.). Первое значение это дельта переменной за 1s, ++ на каждом прерывании . Но частота подчёркнуто изменяется, а число прерываний нет. Как такое может быть, не перестраиваются часы - RegisterA это задание частоты для таймера, он перестраивается хотя нужно проверить!?? - соотв часы системные должны сбиваться, а фикситься через установку KeTimeAdj(NtSetSys..). ps есчо нужно глянуть синхрон при изменении параметров, их много и как там по синхрону хз, механизм сложный.. --- Сообщение объединено, 23 ноя 2021 --- M0rg0t Тебе будет интересно, вот вывод ядра на XP без каких либо трудностей, прямой NtSystemDebugControl. Можно выбирать память виртуальную, физическую, порты и мср. Сделано дыряво, но удобно. Что бы ты такое сделал на 10 тебе придётся собирать сложные драйвера, а в конце этих трудностей пробросить интерфейс по типу как у HoShiMin, впрочем там нерабочее на 51.
"У меня было на W98 при длительных по времени многократно используемых ClI системное время естественно начинает отставать..." ~Пример: за 2 часа работы, отставание в команде "time" и было около того, предположим более полутора часов. Что соответствовало моей оценочной сумме всех интервалов ClI_StI. MS W98 не считывал RTC до перезагрузки, даже по команде "time", а установить ей RTC - пожалуйста. В этом и был сарказм удаленного модератором моего предпоста.