Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности". Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time? Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности". Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time? Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
Мое понимание такое, realtime означает что у системы есть гарантированное время обработки задач (реакции на события).
Ни Windows, ни Linux этого не гарантирует (на прикладном уровне), т.к. система может заняться чем-то своим,
а твоя задача окажется в очереди, и может не выполниться за заданное время.
Даже если запустить 1 процесс, система может его легко приостановить его и заняться обработкой каких-нибудь прерываний например, и заниматься этим столько, сколько захочет.
realtime системе такое не разрешено делать, время отклика должно быть наперед известно.
Здравствуйте, bnk, Вы писали:
bnk>Даже если запустить 1 процесс, система может его легко приостановить его и заняться обработкой каких-нибудь прерываний например, и заниматься этим столько, сколько захочет. bnk>realtime системе такое не разрешено делать, время отклика должно быть наперед известно.
Плюс на уровне ПО, если операция не успевает выполниться, нужно её прекратить и начать следующую. ИМХО.
Здравствуйте, cppguard, Вы писали:
C>Здравствуйте, Maniacal, Вы писали:
M>>Плюс на уровне ПО, если операция не успевает выполниться, нужно её прекратить и начать следующую. ИМХО.
C>Вот это интереснее. Прекратить — отрубить процесс? Или речь о системных вызовах?
Применимо к прошивкам телевизоров, например. Не успел кадр обработать, давай другой начинай.
Здравствуйте, cppguard, Вы писали:
C>без всяких RT-патчей и запустить на нём лишь один про
Если I/O (дрова) предсказуемы, если таймауты точны, то да. Вообще, RT — это в большей части про многозадачность, и соотв. планирование, и в этой теме больше всего ресёрча и сложности проблематики. Один единственный процесс/поток — это вырожденный случай.
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности".
Тоже так думаю. Достигается это ограничением времени на io операции.
C>Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time? Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
Разве не от железа это зависит в первую очередь? Не всякое железо, цпц, для RT задач пригодно, если не ошибаюсь.
Здравствуйте, Sharov, Вы писали:
S>Разве не от железа это зависит в первую очередь? Не всякое железо, цпц, для RT задач пригодно, если не ошибаюсь.
Из того, что в обычном компе какое не подходит и почему? Не вижу проблем каких-то. Понятно, что требования по абсолютным таймингам должны удовлетворяться, а в остальном?
Здравствуйте, student__, Вы писали:
__>Из того, что в обычном компе какое не подходит и почему? Не вижу проблем каких-то. Понятно, что требования по абсолютным таймингам должны удовлетворяться, а в остальном?
Единственное, что приходит в голову — свитчи эзернет, в которых может быть большой диапазон отклика в зависимости от забитости очередей кадров. Но тогда просто не использовать эзернет.
Здравствуйте, cppguard, Вы писали:
C>Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time?
Смотря что вкладывается в эти N секунд. Реалтайм подразумевает, что данные, на основе которых выполняется задача, не успеют "протухнуть" до момента окончания выполнения задачи. Пока твой робот думает N секунд, как ему объехать пешехода, пешеход успел сходить в магазин и обратно, за эти N секунд ))
__>Из того, что в обычном компе какое не подходит и почему? Не вижу проблем каких-то. Понятно, что требования по абсолютным таймингам должны удовлетворяться, а в остальном?
Throttling — частота плавает.
Out of order, Branch Prediction тоже могут приводить к веселым последствиям.
Кэши всякие не дают гарантии по времени доступа к памяти. Помнится для винды был типа патч, который из нее делал типа риалтайм — он вроде как раз логику работы с кэшами правил.
линукс никогда не был реалтаймом
а вообще вопрос с собеседований на котором валят всех
так как никто не знает что вкладывать в этот смысл
для меня примером реалтайма есть QNX
а в ней кажется даже драйвера в ring3
т.е. безотказность и гарантированность исполнения потока данных
как я люблю отвечать на собесах
bnk>Мое понимание такое, realtime означает что у системы есть гарантированное время обработки задач (реакции на события). bnk>Ни Windows, ни Linux этого не гарантирует (на прикладном уровне), т.к. система может заняться чем-то своим,
Вообще-то в винде предусмотрено 32 очереди и первые 16 — как раз для процессов реального времени
Которые имеют приоритет безусловно более высокий, чем вторые 16
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
bnk>>Мое понимание такое, realtime означает что у системы есть гарантированное время обработки задач (реакции на события). bnk>>Ни Windows, ни Linux этого не гарантирует (на прикладном уровне), т.к. система может заняться чем-то своим,
LVV>Вообще-то в винде предусмотрено 32 очереди и первые 16 — как раз для процессов реального времени LVV>Которые имеют приоритет безусловно более высокий, чем вторые 16
IMHO тут как бы речь о том что нельзя быть немножко беременным.
Либо система гарантирует что нечто выполнится в течение наперед заданного времени, либо нет.
LVV>>Вообще-то в винде предусмотрено 32 очереди и первые 16 — как раз для процессов реального времени LVV>>Которые имеют приоритет безусловно более высокий, чем вторые 16
bnk>IMHO тут речь бы речь о том что нельзя быть немножко беременным.
В данном случае — можно... bnk>Либо система гарантирует что нечто выполнится в течение наперед заданного времени, либо нет.
Просто есть разные классы систем реального времени.
Есть системы жесткого реально времени, а есть мягкого.
Основное различие систем жёсткого и мягкого реального времени можно охарактеризовать так:
система жёсткого реального времени никогда не опоздает с реакцией на событие,
система мягкого реального времени не должна опаздывать с реакцией на событие.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, syrompe, Вы писали:
S>Throttling — частота плавает.
отключается
S>Out of order, Branch Prediction тоже могут приводить к веселым последствиям.
просто рассчитывается исходя из худшего сценария.
S>Кэши всякие не дают гарантии по времени доступа к памяти.
То же самое (как с предыдущими пунктами, либо первое, либо второе).
Это я не к тому, что надо именно такие процессоры для всех задач реалтайм использовать, а к тому, что принципиальных проблем нет, если только в худшем сценарии удволетворяются требования к системе.
Здравствуйте, student__, Вы писали:
S>>Разве не от железа это зависит в первую очередь? Не всякое железо, цпц, для RT задач пригодно, если не ошибаюсь.
__>Из того, что в обычном компе какое не подходит и почему? Не вижу проблем каких-то. Понятно, что требования по абсолютным таймингам должны удовлетворяться, а в остальном?
Могу ошибаться, но, насколько я понимаю, в том же Intel поверх ОС есть некий management (Intel Management Engine, вот это вот всё). На него у ОС никакого влияния и доступа нет. При этом он, естественно, для своей работы может забирать процессор. Т.е. предсказуемости нет.
Ещё про DMA слышал много плохого в этом плане, типа может процессор забрать, невзирая на приоритеты.
Кому нужен реалтайм — нужно или использовать микроконтролер, превращающий реалтайм в нереалтайм дополнительно к основному процессору (это, кстати, многие ARM вендоры предоставляют — типа 4-ядерный Application Processor и там же одноядерный микроконтроллер). Или полноценную платформу с софтом (типа QNX) и проверенным железом.
Здравствуйте, vsb, Вы писали:
vsb>Могу ошибаться, но, насколько я понимаю, в том же Intel поверх ОС есть некий management (Intel Management Engine, вот это вот всё). На него у ОС никакого влияния и доступа нет. При этом он, естественно, для своей работы может забирать процессор. Т.е. предсказуемости нет.
Разве не отключается в BIOS?
UPD: в инетах пишут, что правительство США обязало Интел сделать МЕ отключаемым.
Здравствуйте, Sharov, Вы писали:
S>Разве не от железа это зависит в первую очередь? Не всякое железо, цпц, для RT задач пригодно, если не ошибаюсь.
Это определяется тем, где образуются узкие места. Если в железе и около него, то не подходит железо. Если железо всегда укладывается в самые худшие прогнозы, но система в целом в них укладывается не всегда, то проблема, скорее всего, в софте.
Здравствуйте, syrompe, Вы писали:
S>Out of order, Branch Prediction тоже могут приводить к веселым последствиям.
Такие вещи начинают играть заметную роль только вблизи предельного быстродействия аппаратуры. В том, что делается на типовых компьютерах, на это можно не обращать внимания — основные тормоза происходят намного выше.
S>Кэши всякие не дают гарантии по времени доступа к памяти. Помнится для винды был типа патч, который из нее делал типа риалтайм — он вроде как раз логику работы с кэшами правил.
Это сугубо о программных кэшах — страничных, дисковых, файловых и прочих.
Здравствуйте, student__, Вы писали:
S>>Разве не от железа это зависит в первую очередь? Не всякое железо, цпц, для RT задач пригодно, если не ошибаюсь. __>Из того, что в обычном компе какое не подходит и почему? Не вижу проблем каких-то. Понятно, что требования по абсолютным таймингам должны удовлетворяться, а в остальном?
А как гарантировать, что io диска всегда будет не больше чего-то там?
Здравствуйте, LaptevVV, Вы писали:
LVV> bnk>IMHO тут речь бы речь о том что нельзя быть немножко беременным. LVV> В данном случае — можно... LVV> bnk>Либо система гарантирует что нечто выполнится в течение наперед заданного времени, либо нет. LVV> Просто есть разные классы систем реального времени. LVV> Есть системы жесткого реально времени, а есть мягкого.
И дефолтная винда не относится, ни к тем, ни к другим. Читайте об этом у Соломона и Русиновича (Внутреннее устройство Windows 2000. глава 3. стр. 86), они прямо об этом говорят и объясняют почему.
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности". Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time? Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
Вы путаете ос реального времени и система реального времени. Общее в этих вещах — время отклика. Разница в том, кто дает эти гарантии.
Дело не в том, сколько процессов и кто чем занят, а какие шансы, что время отклика превысит ожидаемое.
Теоретически, систему реального времени с конским временем отклика, типа наблюдения за погодой, управление антеной тв, можно построить на обычной ос, отключив в ней все что можно.
А если требуемое время отклика это доли секунды, то нужна ОС рв, в противном случае вы никакие гарантии не получите.
Например, в винде Sleep в средем выполняется ровно столько, сколько вы запросили. Но под нагрузкой может увеличиваться в десятки раз. Мне удавалось добиться Sleep(1000) в 15 и более секунд.
В ОС рв приоритет потока, который выполняет Sleep становится максимальным к моменту завершения интервала, потому этот поток получит выполнение точно в срок. В винде — никаких гарантий нет.
Так же в винде время обычного системного вызова может быть сколь угодно большим. А в ОСРВ оно более-менее детериминировано.
Еще одна из проблем, которые решены в ОСРВ — инверсия приоритетов. Когда высокоприоритетный поток ждет ресурс который занят низкоприоритетным, а тот не выполняется, т.к. время занимает поток среднего приоритета.
В ОСРВ низкоприоритетный поток получит наивысший приоритет как только высокоприоритетный начнет ожидать ресурс.
Здравствуйте, Sharov, Вы писали:
S>Вроде одно из св-в и определений RT, это bounded io. Т.е. речь о любой периферии в том числе.
я могу загрузиться с перфокарт, и дальше начать работать, со всем I/O столько в сети.
Диск сам по себе не особо надёжен, так что его использование в ответственных применениях, когда нужна именно гарантия записи с дедлайном, так себе идея.
И потом, в системе реального времени не вся периферия обязана быть bounded. На НМЖД можно, например, сбрасывать логи, которые потерять не 100% критично, и которые будут писаться на фоне. Для SSD наверняка проще получить априори худшее время записи.
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности". Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time? Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
Если сможешь доказать, что прога + ос (т.е. все целиком) ВСЕГДА реагирует на внешние раздражители за некоторое наперед известное время, то система будет системой реального времени, отчего ж нет.
Здравствуйте, LaptevVV, Вы писали:
LVV>Вообще-то в винде предусмотрено 32 очереди и первые 16 — как раз для процессов реального времени LVV>Которые имеют приоритет безусловно более высокий, чем вторые 16
Это имеется ввиду, "типа риалтайм".
В венде драйвера могут занять систему своим полезным делом в любой момент, когда захотят, и на произвольное время. Так что венда может очень постараться, но не может ничего гарантировать.
Здравствуйте, Sharov, Вы писали:
S>Разве не от железа это зависит в первую очередь? Не всякое железо, цпц, для RT задач пригодно, если не ошибаюсь.
Не очень понятно, что такого может быть упущено в железе, чтобы оно не годилось для RT. Но вот драйвера железа дейтвительно бывают разного качества. И иные будут серьезно мешаться риалтаймовости.
Здравствуйте, reversecode, Вы писали:
R>линукс никогда не был реалтаймом
Так потому и пример с линуксом. Куча роботов и станков работают на нём, приборные панели в автомобилях. При этом, насколько я знаю, даже RT-patch не превращает Linux в аналог QNX.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>То есть, даже статей в википедии на эту тему Вы не читали? ЕМ>Если читали, то чего именно там не хватает для понимания?
Читал. Там классический трактат, который дают в универах: про soft- и hard- real-time, про абстрактное понятие "задачи", но ни слова про конкретные инструменты или примеры.
Здравствуйте, Pzz, Вы писали:
Pzz>Не очень понятно, что такого может быть упущено в железе, чтобы оно не годилось для RT. Но вот драйвера железа дейтвительно бывают разного качества. И иные будут серьезно мешаться риалтаймовости.
Я слышал про режимы работы цпу, мол защищенный режим не годится для rt.
Здравствуйте, Sharov, Вы писали:
Pzz>>Не очень понятно, что такого может быть упущено в железе, чтобы оно не годилось для RT. Но вот драйвера железа дейтвительно бывают разного качества. И иные будут серьезно мешаться риалтаймовости.
S>Я слышал про режимы работы цпу, мол защищенный режим не годится для rt.
Здравствуйте, cppguard, Вы писали:
C>Читал. Там классический трактат, который дают в универах: про soft- и hard- real-time, про абстрактное понятие "задачи", но ни слова про конкретные инструменты или примеры.
Вот пример:
while (true)
{
t1 = read_input(x)
adjust_read_time(t1)
y = f(x)
t2 = write_output(y)
adjust_write_time(t2)
}
Здравствуйте, cppguard, Вы писали:
C>Ничего из него непонятно.
Тогда проще: представьте, что Вы работаете на конвейере, по которому движутся, скажем, тонкие стеклянные изделия, которые Вам нужно упаковывать в коробки. Конвейер может иметь следящее устройство, которое останавливает его, если Вы не успеваете снять очередное изделие, а может и не иметь его. Скорость Вашей работы может быть как выше скорости конвейера, так и ниже нее.
— Если Вы всегда успеваете вовремя снять изделие, и аварийная остановка никогда не срабатывает, или вообще не предусмотрена — это hard realtime.
— Если Вы обычно успеваете, но в редких случаях остановка таки срабатывает — это soft realtime. Здесь также возможно, что остановки не происходит, и изделие разбивается (теряется безвозвратно). Предполагается, что такие случаи не наносят заметного вреда общему процессу. Так работает, например, передача по UDP, что не мешает организовать по TCP вполне надежную передачу звука или видео в реальном времени.
— По мере увеличения частоты остановок из-за неуспевания уменьшается возможность отнесения процесса к realtime.
Здравствуйте, cppguard, Вы писали: C>Ничего из него непонятно.
лучше читать книги, чем спрашивать на форуме
C>Вот в обсуждении прояснили кое-какие моменты. Как, например, разница в real-time system и real-time OS.
Во-первых, до этого легко можно было бы догадаться, зная, что для любого программно-аппаратного комплекса задаются системные требования и ПО требования.
Во-вторых, ничего особенно практического эта инфа не добавляет в общее понимание проблемы.
Pzz>>Не очень понятно, что такого может быть упущено в железе, чтобы оно не годилось для RT. Но вот драйвера железа дейтвительно бывают разного качества. И иные будут серьезно мешаться риалтаймовости. S>Я слышал про режимы работы цпу, мол защищенный режим не годится для rt.
Возможно речь шла про подкачку виртуальной памяти, для которой нужен защищенный режим но которую совершенно необязательно использовать в защищенном режиме.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Тогда проще: представьте, что Вы работаете на конвейере, по которому движутся, скажем, тонкие стеклянные изделия, которые Вам нужно упаковывать в коробки. Конвейер может иметь следящее устройство, которое останавливает его, если Вы не успеваете снять очередное изделие, а может и не иметь его. Скорость Вашей работы может быть как выше скорости конвейера, так и ниже нее.
ЕМ>- Если Вы всегда успеваете вовремя снять изделие, и аварийная остановка никогда не срабатывает, или вообще не предусмотрена — это hard realtime.
ЕМ>- Если Вы обычно успеваете, но в редких случаях остановка таки срабатывает — это soft realtime. Здесь также возможно, что остановки не происходит, и изделие разбивается (теряется безвозвратно). Предполагается, что такие случаи не наносят заметного вреда общему процессу. Так работает, например, передача по UDP, что не мешает организовать по TCP вполне надежную передачу звука или видео в реальном времени.
Вот это типичное университетское объяснение real-time. И проблема в том, что даже непрограммист легко поймёт задачи систем реального времени и принцип разделения на soft, firm и hard. А у программистов другие вопросы:
— какую систему считать real-time?
— какими качествами должна обладать эта система?
— чем принципиально (кроме микроядра) QNX отличается от Linux?
— является ли Minix real-time OS?
— почему роботы работают на Linux, хотя это не real-time OS?
— почему моя магнитола иногда жёстко тупит и зависает, хотя внутри QNX?
Здравствуйте, cppguard, Вы писали:
C>- какую систему считать real-time?
Такую, которая обеспечит решение задачи в заданных рамках. То есть, для линии по сортировке/упаковке яиц может сгодиться и soft realtime, пока процент боя не выходит за допустимые пределы. А для управления реактором уже потребуется hard realtime (в пределах требуемой надежности).
Ну и надо понимать, что бессмысленно повышать надежность realtime в отрыве от общей надежности всей системы (железо+периферия+ОС+софт). Если, скажем, вероятность пропуска события — 1E-8, а вероятность глюка памяти — 1E-7, то особого смысла в таком строгом realtime нет.
C>- какими качествами должна обладать эта система?
Из обязательных — выполнять требуемые действия в пределах отведенного для них времени. Все остальное можно сделать на более высоких уровнях. Ну и понятно, что совокупное быстродействие должно быть достаточным для решения поставленных задач. Например, если железо и ОС гарантируют своевременный прием и передачу видеокадров, но прикладной софт сделали такой, что обрабатывать эти кадры он не успевает, от realtime особого толку не будет.
C>- чем принципиально (кроме микроядра) QNX отличается от Linux?
Тут не скажу, я не спец по обеим. Но в Linux многое делают системные службы (демоны), которые являются обычными пользовательскими процессами, разве что с повышенным приоритетом. В QNX они явно тоже переработаны.
C>- является ли Minix real-time OS?
Вообще ничего о ней не знаю.
C>- почему роботы работают на Linux, хотя это не real-time OS?
И Linux, и Windows, и MacOS — это не hard realtime, но вполне себе soft realtime с достаточно малым временем реакции, если грамотно настроены. Если от робота не требуется гарантированного времени реакции в единицы миллисекунд, он может работать даже на винде.
C>- почему моя магнитола иногда жёстко тупит и зависает, хотя внутри QNX?
Возможно, это как раз случай сочетания строгой ОС с не пойми каким софтом. Типа, заказчик где-то прочитал про realtime и QNX, и потребовал сделать магнитолу на ней. А софт и GUI, как водится, писали на куче разношерстных фреймворков, оно и тормозит, и никакая ОС это спасти не сможет.
Здравствуйте, Евгений Музыченко, Вы писали:
Pzz>>В венде драйвера могут занять систему своим полезным делом в любой момент, когда захотят, и на произвольное время.
ЕМ>А в каких ОС они этого не могут? Какие ОС умеют жестко ограничивать время работы драйверов, не нарушая при этом работу периферии?
Ну как вариант, пытаться решать проблему не в рантайме, давая драйверу по мозгам, а организационно, не стараясь не пропускать кривых драйверов в систему.
Здравствуйте, bnk, Вы писали:
bnk>Мое понимание такое, realtime означает что у системы есть гарантированное время обработки задач (реакции на события).
Это так и есть — любое событие обрабатывается за заранее заложенное время. Если такое не соблюдается, это уже не система реального временни — она опаздывает. В случае АЭС это взрыв реактора. Так что на АЭС должны быть только настоящие системы реального времени и без багов, иначе на милисекунду замедлить поднятие стрежня в реакторе — может и цепная ядерная реакция произойти. Это совсем другие системы и софт иной.
Здравствуйте, cppguard, Вы писали: C>Посоветуешь что-нибудь годное по теме?
Единственное, что я читал — "Real-Time Systems and Programming Languages. Ada, Real-Time Java and C/Real-TIme POSIX", Alan Burns, Andy Wellings.
Это такая мешанина из примеров кода и теории.
Наверняка есть и другие книги, и может лучше.
Здравствуйте, _ilya_, Вы писали:
__>Это так и есть — любое событие обрабатывается за заранее заложенное время. Если такое не соблюдается, это уже не система реального временни — она опаздывает. В случае АЭС это взрыв реактора. Так что на АЭС должны быть только настоящие системы реального времени и без багов, иначе на милисекунду замедлить поднятие стрежня в реакторе — может и цепная ядерная реакция произойти. Это совсем другие системы и софт иной.
Все верно, кроме взрыва. Системы аварийного выключения дублированы в другом контуре управления и от основного компа системы управления не зависят. Ну и процессы там не настолько быстро развиваются, чаще всего успевает среагировать даже оператор.
Это конечно предположения, а не инсайд, но вот так примерно в таких системах все и делается. А не на основе надежды на абсолютно правильное железо и безупречный софт.
Здравствуйте, Pzz, Вы писали:
Pzz>пытаться решать проблему не в рантайме, давая драйверу по мозгам
А что, ее таки можно решить такими методами? Сможете описать хоть мало-мальски реалистичный сценарий?
Pzz>а организационно, не стараясь не пропускать кривых драйверов в систему.
И чем тогда будет отличаться "истинно риалтаймовая" система от "условно риалтаймовой"?
Здравствуйте, Евгений Музыченко, Вы писали:
Pzz>>а организационно, не стараясь не пропускать кривых драйверов в систему.
ЕМ>И чем тогда будет отличаться "истинно риалтаймовая" система от "условно риалтаймовой"?
Ну, вероятно, наличием риалтаймовых сертификационных требований к драйверам.
Здравствуйте, Pzz, Вы писали:
ЕМ>>И чем тогда будет отличаться "истинно риалтаймовая" система от "условно риалтаймовой"?
Pzz>Ну, вероятно, наличием риалтаймовых сертификационных требований к драйверам.
Ну так в той же NT такие требования существуют еще с самых ранних версий, но на них систематически забивает сам MS. А его тесты HCK/HCK этих параметров, насколько я знаю, вообще никогда не проверяли.
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности". Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time? Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
как уже описали, наиболее критические процессы не выполняются на известных нам ОС, даже если
достаточно ядер и дать процессу высокий уровень приоритета — окончательных гарантий нет.
однако понятие реального времени растяжимо. если на внеший триггер сможешь гарантировать выполнение
операции и ответ до прихода следующго, тоесть вписываешся в такт — значит работаешь в режиме реального времени.
как ты это сделаешь, тут много вариантов
Здравствуйте, pik, Вы писали:
pik>как ты это сделаешь, тут много вариантов
Меня вот это конкретно интересует. Детские определения из учебника я прочитал много лет назад =) По факту получается, что многие системы, которые должны быть в реальном времени, на самом деле таковыми не являются. Их пишут на линупсе, надеясь, что всё будет как-то работать. Тот же ROS2. Или пишут bare metal, где вообще сложно не быть real-time, и говорят, что это real-time.
Здравствуйте, cppguard, Вы писали: C>По факту получается, что многие системы, которые должны быть в реальном времени, на самом деле таковыми не являются. Их пишут на линупсе, надеясь, что всё будет как-то работать.
Уже писали тут. Проигрывание видео — это пример реал-тайма. Пока нет конкретных требований, сложно сказать про абстрактную систему, нарушает она их или нет.
Если ты про роботов всяких, типа service robots, которыми в универах развлекаются, что-то не видел, чтобы к ним какие-то жесткие требования предъявляли.
C>Тот же ROS2.
Последний раз, когда я смотрел ROS — это был фреймворк для написания параллельно выполняющихся нод, с собственным механизмом передачи сообщений, "стандартными" типами данных и готовые ноды для всяких SLAM и проч. Хард-реалтаймом он себя (тогда) не называл, и потом, он не определял планирование задач, этим занималось ядро ОС.
>Или пишут bare metal, где вообще сложно не быть real-time
Вот вообще ортогональные вещи. Что мне мешает написать бейр-метал, в котором будут несколько тасков без инверсии приоритетов, и таск с нисшим приоритетом будет "душить" таск с высшим приоритетом?
Здравствуйте, student__, Вы писали:
__>Уже писали тут. Проигрывание видео — это пример реал-тайма. Пока нет конкретных требований, сложно сказать про абстрактную систему, нарушает она их или нет. __>Вот вообще ортогональные вещи. Что мне мешает написать бейр-метал, в котором будут несколько тасков без инверсии приоритетов, и таск с нисшим приоритетом будет "душить" таск с высшим приоритетом?
То ли не встречался с проблемой, то ли прикалываешься. Как я видел в своей жизни объяснение реального времени. Дают пример с потоковым декодированием аудио-видео. Тут как бы всё понятно, soft real-time, нет вопросов. Дальше — дают пример с бортовым компьютером в автомобиле и говорят что-то типа: "Если ABS сработает в нужный момент, то может случиться авария, поэтому вот пример hard real-time". И я начинаю размышлять: "Окей, а какие методы позволяют достичь этого самого rea-time? Может есть алгоритмы? Или методы верификаии?". И правильный ответ — да, методы есть, их много, они разные. И про них никто тебе не расскажет, нужно самому копать. А блок ABS просто написан на bare metal, там полностью детерминистичный алгоритм, который при всём желании не может дать случайные задежки. Поэтому ABS это пример real-time system, но не real-time подхода к разработке. А меня, как разработчика, в первую очередь интеруют именно инструменты предоставления гарантии real-time.
__>Последний раз, когда я смотрел ROS — это был фреймворк для написания параллельно выполняющихся нод, с собственным механизмом передачи сообщений, "стандартными" типами данных и готовые ноды для всяких SLAM и проч. Хард-реалтаймом он себя (тогда) не называл, и потом, он не определял планирование задач, этим занималось ядро ОС.
The Robot Operating System без гарантии real-time это какая-то нелепица. Если посмотреть на задачи, которыми занимались основатели — The Willog Garage, то становится понятно, что реальное время там и не нужно было, я всё это понимаю, но абсурда это не отменяет. А если верить Википедии, то наработки компании после её продажи использовались во вполне себе серьёзных проектах.
Здравствуйте, pagid_, Вы писали: _>Это конечно предположения, а не инсайд, но вот так примерно в таких системах все и делается. А не на основе надежды на абсолютно правильное железо и безупречный софт.
Есть и другие примеры — скажем, система стабилизации какого-нибудь F22. Сам по себе он аэродинамически неустойчив, и если компьютер опоздает с вычислением управляющего воздействия в ответ на порыв ветра, то машинка просто рассыплется в воздухе. Поэтому там всё работает именно на основе надежды на абсолютно правильное железо (с тройной, емнип, избыточностью) и безупречный софт.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, cppguard, Вы писали: >А меня, как разработчика, в первую очередь интеруют именно инструменты предоставления гарантии real-time.
Рекомендую ту книгу, которую я упомянул. Там нет про конкретные ОС, но есть теоретическая инфа о том, как, например, верифицируется непропуск планировщиком дедлайнов для конкретных типов систем, с наперёд известными пиковыми нагрузками (частотой некоего события) и максимальных длительностей отдельных операций, составляющих решаемую техническую задачу.
Изучив некоторую базу теории уже можно рассматривать конкретную ОС и проч. инструменты, сам я пока до этого не дошёл.
C>The Robot Operating System без гарантии real-time это какая-то нелепица. Если посмотреть на задачи, которыми занимались основатели — The Willog Garage, то становится понятно, что реальное время там и не нужно было, я всё это понимаю, но абсурда это не отменяет. А если верить Википедии, то наработки компании после её продажи использовались во вполне себе серьёзных проектах.
Ну видимо не в совсем серьёзных, в которые абы какой POSIX не пустят. А для сервис-робота особой разницы нет, сработает ли блокировочный бампер к моменту t0 или t0+5ms.
Здравствуйте, cppguard, Вы писали: >Поэтому ABS это пример real-time system, но не real-time подхода к разработке. А меня, как разработчика, в первую очередь интеруют именно инструменты предоставления гарантии real-time.
Это вряд ли тот пример, на котором вся сложность реалтайма с т.з. софта и планирования возникает во всей красе, а здесь больше про автоматическое управление, обратную связь и всё такое. На входе поступает инфа от фиксированного количества датчиков, решается оптимизационная задача, где каждая итерация вычисления занимает фиксированное время. В результате управляющий сигнал подаётся на выход. С т.з. софта это, например, тот же бизи луп и поллинг, и основная сложность в хардовой архитектуре и выборе конкретных МК и шин данных, чтобы уложиться в максимальные величины длительности В/В и вычисления целевой функции. Если абсолютные величины (например, по шине ходят ещё какие-то данные от других подсистем) не фиксированы, может потребоваться контроль джиттера В/В, но хрен знает, нужно ли это для ABS.
И ABS'у связь с приборной панелью и остальным инфотейнментом нужна разве чтобы отправить "я сработал" или "я неисправен" в журнал событий или на приборную панель, но отправка этого всего тоже включается в расчет итерации бизи лупа.
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности".
Под этим термином могут пониматься разные вещи. Но в самом общем виде, это когда для работы программы имеет значение реальное (физическое) время, которое мы измеряем с помошью реальных (физических) часов.
Например, компьютерные игры бывают пошаговые, а бывают реального времени. В пошаговых играх время тоже может идти, например в Цивилизации за каждый ход проходит некоторое количество лет, но к физическим часам это отношения не имеет. В игре же реального времени, игровое время соответствует физическому, при этом гарантии, что игра не будет ингода притормаживать тебе никто не дает.
C>Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time?
Допустим у тебя есть обыкновенный видеофайл. В нем есть обычное видео, записанное с частотой 25 кадров в секунду и длиной 10 секунд. Тебе надо проиграть этот файл в реальном времени. У тебя мощное железо и хороший софт, который позволяет обработать и показать кадр 10 раза быстрее. То есть ты можешь проиграть 10 секундное видео за 1 секунду. По идее, если ты проиграешь видео за 1 секунду, ты в 10 секунд укладываешься, даже с большим запасом. Но это не real-time! Чтоб проиграть видео в реальном времени, время на видео должно идти с той же скоростью, что и физическое.
Если же у тебя слабое железо, и ты не успеваешь обрабатывать кадр за нужное время, ты можешь начать выкидывать какие-то кадры, ухудшить качество видео и тд и тп, но все равно проиграть его за те же 10 секунд.
C>Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
Я специально ничего не стал писать про ОС реального времени. Это уже более узкое понятие. Если запущенный тобой процесс вообще не имеет никакого отношения к физическому времени, а просто что-то вычисляет, то он не будет real-time, даже если ты его запустишь на QNХ.
Здравствуйте, cppguard, Вы писали:
C>The Robot Operating System без гарантии real-time это какая-то нелепица.
Нелепица — это неумение прочитать первый абзац Википедии:
Robot Operating System (ROS or ros) is an open-source robotics middleware suite. Although ROS is not an operating system (OS) but a set of software frameworks for robot software development, it provides services designed for a heterogeneous computer cluster such as hardware abstraction, low-level device control, implementation of commonly used functionality, message-passing between processes, and package management.
говорят что MS DOS досихпор летает в космосе одно из упоминаний
В конце 1993 года российская компания Физтех-софт выпускает первую коммерческую версию PTS-DOS v6.4 (номер версии следует системе версий MS-DOS — Microsoft выпустила MS-DOS v6.2 в ноябре 1993 года).
Некоторые программисты, покинувшие Физтех-софт в 1995 году и основавшие Paragon Software выпустили собственную версию PTS-DOS v6.51CD с поддержкой приводов CD-ROM.
Физтех-софт продолжила разработку своего кода, выпустила PTS-DOS v6.6 и показала PTS-DOS v6.65 на выставке CeBIT в 1997 году[1]. Следующая версия от Физтех-софт, PTS/DOS Extended Version 6.70, выпускалась под названием PTS-DOS 2000 и продается до сих пор (начало 2009 года), как последний 16-битный PTS-DOS. Система ДОС Багет, основанная на PTS-DOS 2000, сертифицирована Министерством обороны Российской Федерации.
Paragon продолжил разработку линии PTS-DOS и выпустил Paragon DOS Pro 2000 (также известный как PTS/DOS Pro 2000) с поддержкой файловой системы FAT-32 и жёстких дисков более 8 гигабайт. Согласно сообщениям Paragon, это была последняя версия и вся разработка с тех пор была прекращена. Эта версия поставлялась с исходным кодом более старого PTS-DOS v6.51.
В 2002 году Физтех-софт выпустил 32-битную версию PTS-DOS — PTS-DOS 32 (известный как PTS-DOS v7.0[2]) с поддержкой файловой системы FAT-32, жёстких дисков более 8 гигабайт и памяти до 4 гигабайт.
Здравствуйте, sergey2b, Вы писали:
S>говорят что MS DOS досихпор летает в космосе одно из упоминаний
Так и Вояджеры до сих пор летают. Типа, кто там их из этого космоса достанет.
С другой стороны, в космосе, как и в автомобилях, всегда был очень длинный жизненный цикл железа: пока спроектируют, потом в серию выведут, потом эту серию надо годами поддерживать.
Здравствуйте, Nuzhny, Вы писали:
N>Нелепица — это неумение прочитать первый абзац Википедии: N>
N>Robot Operating System (ROS or ros) is an open-source robotics middleware suite. Although ROS is not an operating system (OS) but a set of software frameworks for robot software development, it provides services designed for a heterogeneous computer cluster such as hardware abstraction, low-level device control, implementation of commonly used functionality, message-passing between processes, and package management.
Robot Operating System is not an operating system — не вижу подвоха. Я прексрасно знал и до этого, что ROS не реализует какие-то реальные вещи из мира роботов, а является по сути скоплением алгоритмов кинематики, управления и т.д. Но в реального робото всё это не воткнуть.
Здравствуйте, cppguard, Вы писали:
C>Но в реального робото всё это не воткнуть.
Зависит от робота. ROS — это же наполовину образовательный проект Стэнфорда, где студент может взять какой-то узкий алгоритм, реализовать только его с правильным интерфейсом и весь пайплайн будет работать. Например, SLAM — классический пример использования. На модельках или даже в симуляторе, без проблем.
В Боинг ROS не засунут, на конвейер тоже, военные использовать его не станут, Тесла к себе не поставит. Но штука хорошая для своей ниши.
Здравствуйте, cppguard, Вы писали:
C>Может есть алгоритмы? Или методы верификаии?". И правильный ответ — да, методы есть, их много, они разные. И про них никто тебе не расскажет, нужно самому копать.
А что про них рассказывать-то в общем случае? Это как про таблицу умножения монографию писать. Оно ж и так понятно: нужно убедиться, что по всем путям выполнения сумма всех возможных задержек не превышает некоторых разумных величин, определяемых или интуитивно, или статистически. Если делается программа для голого процессора — учитываем его внутренние задержки и задержки самой программы. Если используются внешние устройства — добавляем задержки шин и устройств. Используется ОС — добавляем задержки ядра, драйверов и приоритетных служб. Используются библиотеки — добавляем их задержки.
А о том, как устранить лишние задержки в тех или иных устройствах и системах, написано до хренища. Просто оно не стоит на одной полке.
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности". Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time? Если взять Linux, без всяких RT-патчей и запустить на нём лишь один процесс, который в цикле без ветвлений что-нибудь считать, будет ли такая система real-time?
Основательно погрузился в этот процесс в декабре, поэтому отвечаю сам себе. Прежде всего, "real-time" это очень широкий термин, который охватывает разные уровни системы. Если речь идёт именно про операционные системы, то "real-time OS" означает наличие планировщика, работающего в соответствии с жёстко вытесняющей моделью (это моя вольная трактовка). Проще говоря, real-time scheduler выполняет задачу (системный поток), пока она не заблокируется в ожидании ввода-вывода, примитива синхронизации, вызова sleep() или не передаст управление явно, вызовав yield(). Как только самый приоритетный поток завершился или заснул, планировщик выбирает следующую задачу с таким же приоритетом или ниже, если нет задач с таким же приоритетом. При этом для задач с равным приоритетом могут использоваться разные политику выбора. Например, политика FIFO устанавливает очерёдность исполнения на основании очерёдности добавления в очередь. То есть, задачи добавленыые (запланированные) ранее будут исполнены первее. Другая политика, Round-Robin, позволяет исполнять задачи с равным приоритетом всевдо-параллельно, предоставляя каждой фиксированную порцию вермени исполнения. Для сравнения, планировщики Linux и Windows тоже учитывают приоритет, но при этом стараются дать квант времени даже для задач с низким приоритетом, потому что в данном случае значение отклика системы гораздо важнее. В конкретных ОСРВ могут встречаться специфичные политики. Например, SCHED_DEADLINE в Linux позволяет задать для задачи ограничение по сроку исполнения — тот самый функционал, который приводят в абстрактных примерах. В случае этой политики планировщик выбирает следующую задачу на основании заявленного времени работы и времени завершения. Планировщик (в данном случае является синонимом "политики") deadline хорошо иллютстрирует отличие ОСРВ от обычных систем. В QNX deadline в случае нарушения гарантий времени работы со стороны приложения позволяет установить обработчик соответствующего события и обработать его программно, Linux же ничего не делает кроме понижения приоритета задачи. Помимо планировщика ОСРВ отличаются общей предсказуемостью времени работы обработчиков прерываний и системных вызовов. А ещё есть разные дополнительные инструменты. Например, partitions в QNX позволяют разделить ресурсы ЦП между кластерами задач в заранее заданом соотношении. Так можно отдать 20% на некритичные задачи и 80% на критичные, а ОС сама позаботится о распределении ресурсов. Отдельно я бы выделил прикладные приёмы программирования для задач реального времени, как, например, отказ от динамической памяти, или повсеместное использование в STL C++ детерминированного аллокатора, или вообще Epsilon GC для Java c жёстким контролем за выделением памяти. Но про это очень мало написано.
Если говорить про разделение на категории, то можно выделить три группы. Первая — это коммерские ОСРВ вроде QNX и VxWorks. Вторая группа это открытые ОСРВ, которые собираются вместе с приложением, например, FreeRTOS и RIOT. Я не знаю, есть там разделение на уровень ядра и на прикладной, но уже один факт того, что эти ОС по сути являются частью приложения, заставляет изучать их в особом порядке. Наконец, есть Linux, обросший за долгие годы многими инструментами, присущими ОСРВ, а в недавнем прошлом ещё и получивший PREEMPT_RT в основную ветку. Зачем я привёл эти три группы? Да просто потому что если мы начинаем рассуждать о системах реального времени (операционных в том числе), то нужно чёткое понимание, что именно мы обсуждаем, а иначе будет блуждание в тумане.
Подытоживая написанное в одном предложении: ОСРВ это прежде всего чёткая очерёдность задач в соответствии с их приоритетами, и ещё некоторые другие инструменты, позволяющие наиболее эффективно использовать вычислительные ресурсы, сохраняя гарантию успеть выполнить задачу до того, как результат станет неактуальным.
Здравствуйте, Maniacal, Вы писали:
C>>Вот это интереснее. Прекратить — отрубить процесс? Или речь о системных вызовах? M>Применимо к прошивкам телевизоров, например. Не успел кадр обработать, давай другой начинай.
Ну, не зря же программа Время начинается на цифровых телеках/приставках примерно на пол-секунды, а то и секунду позже, чем на аналоговых... ))
Здравствуйте, Евгений Музыченко, Вы писали:
Pzz>>В венде драйвера могут занять систему своим полезным делом в любой момент, когда захотят, и на произвольное время. ЕМ>А в каких ОС они этого не могут? Какие ОС умеют жестко ограничивать время работы драйверов, не нарушая при этом работу периферии?
Тут дело не только в ОС, а еще в конкретном оборудовании и настройке самой ОС, в т.ч. настройки её при компиляции ядра.
И Windows, и Linux могут быть собраны таким образом для конкретной железки, чтобы, допустим, прерывания обрабатывались только нулевым ядром.
В этом случае даже "короткое" аппаратное прерывание, маскирующая другие прерывания, не заденет процессы, исполняющиеся в других ядрах, а там уже вопрос приоритета, если есть боязнь вытеснения — в виндах отродясь был realtime-приоритет, для linux есть соотв. патчи.
А для "длинных" софтовых прерываний в этих ОС никогда не было проблем одновременной их обработки.
В общем, это вопрос сочетания сборки ядра, распределения аппаратных ресурсов (в т.ч. назначения affinity для прикладных потоков) и взаимодействия драйвера устройства и прикладного кода, требующего реалтайм.
Например, не стоит создавать взаимные блокировки ресурсов у драйвера и прикладной части, стоит использовать lock-free техники.
С сигналингом тоже достаточно просто — прикладной процесс может находиться в режиме ожидания на некоем HEVENT, имея при этом realtime-приоритет, а драйвер, после подготовки данных, может дёрнуть этот примитив синхронизации и тогда прикладной процесс получит в своём привязанном через affinity аппаратном потоке ресурс проца.
Ну и, сам прикладной код может целиком жить в драйвере, хотя в этом случае писать придётся на Си или на сильно урезанном С++ — без исключений/RAII, без динамической инициализации глобальных объектов, без RTTI и, возможно, без сохранения плавающих регистров м/у прерываниями, т.е., подавляющее большинство плюсовых библиотек использовать будет невозможно.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>И Linux, и Windows, и MacOS — это не hard realtime, но вполне себе soft realtime с достаточно малым временем реакции, если грамотно настроены. Если от робота не требуется гарантированного времени реакции в единицы миллисекунд, он может работать даже на винде.
На Win XP работает ЧПУ софтина Mach3, которая напрямую управляет шаговыми двигателями с частотой как минимум в килогерцы, а то и десятки. И если бы там профукивались тайминги, то траектория была бы не совсем та, которую хотелось бы
Здравствуйте, cppguard, Вы писали:
C>Думал, что, начав заниматься робототехникой, окончательно разберусь с этим термином. Пока что для меня real-time является синонимом "детерминистичности". Есть ли разница между "успеет выполнить задачу за N секунд" и пониятием real-time?
Лично для меня realtime в ОС в первую очередь означает гарантированное время, от прихода события, до момента, когда начали выполняться первые инструкции обработчика события.
Например, устройство по DMA заполнило буфер и вызвало аппаратное событие, которое в свою очередь вызвало прерывание, внутри которого ОС было уведомлено, что данные готовы, после чего (уже не в прерывании, а в задаче ОС в пользовательском коде) начали обрабатываться данные. В данном случае, если от момента, когда железо вызвало событие, до момента обработки данных в пользовательском коде, промежуток детерминирован, то это realtime, если не детерминирован и зависит от фазы Луны, то не realtime
Здравствуйте, vdimas, Вы писали:
V>В этом случае даже "короткое" аппаратное прерывание, маскирующая другие прерывания, не заденет процессы, исполняющиеся в других ядрах
Не знаю, как в Linux, а в Windows аппаратные прерывания — один из последних факторов, влияющих на реактивность процессов. На современном железе нужны десятки-сотни тысяч прерываний в секунду, чтобы они стали ощутимо кому-то мешать. В основном тормозят кривые драйверы (в том числе родные) и чрезмерно раздутый код ядра.
V>в виндах отродясь был realtime-приоритет, для linux есть соотв. патчи.
Это всего лишь наивысший приоритет user-mode кода. От тормозов в ядре он спасти не может.
V>не стоит создавать взаимные блокировки ресурсов у драйвера и прикладной части, стоит использовать lock-free техники.
Стоит, но кто бы это делал в той же винде...
V>прикладной код может целиком жить в драйвере, хотя в этом случае писать придётся на Си или на сильно урезанном С++ — без исключений/RAII, без динамической инициализации глобальных объектов, без RTTI и, возможно, без сохранения плавающих регистров м/у прерываниями, т.е.,
RAII не требует ничего, кроме поддержки конструкторов/деструкторов, это реализовано везде. А что такое "динамическая инициализация глобальных объектов"?
V>подавляющее большинство плюсовых библиотек использовать будет невозможно.
Их уже из-за исключений невозможно использовать. Ну и еще потому, что про наличие небесконечной памяти их авторы, похоже, забыли уже очень давно.
Здравствуйте, пффф, Вы писали:
П>На Win XP работает ЧПУ софтина Mach3, которая напрямую управляет шаговыми двигателями с частотой как минимум в килогерцы, а то и десятки.
Если конфигурация системы тщательно вылизана, то вполне реально. А вот устроить такое в обычной домашней/офисной системе с интернетом и мультимедиа уже вряд ли получится, хотя чисто технически ничто не мешает.
Здравствуйте, Евгений Музыченко, Вы писали:
П>>На Win XP работает ЧПУ софтина Mach3, которая напрямую управляет шаговыми двигателями с частотой как минимум в килогерцы, а то и десятки.
ЕМ>Если конфигурация системы тщательно вылизана, то вполне реально. А вот устроить такое в обычной домашней/офисной системе с интернетом и мультимедиа уже вряд ли получится, хотя чисто технически ничто не мешает.
Ничего там не вылизывалось, ставил на древнюю систему самую обычную древнюю XPшку, по сети закидывал файлы с жи кодом, и пилил
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Не знаю, как в Linux, а в Windows аппаратные прерывания — один из последних факторов, влияющих на реактивность процессов.
Это от драйвера зависит.
Маскируемое прерывание должно быть отработано как можно быстрее, т.е. в идеале — выставить пару флагов, разрешить аппаратные прерывания и инициировать уже программное прерывание.
ЕМ>На современном железе нужны десятки-сотни тысяч прерываний в секунду, чтобы они стали ощутимо кому-то мешать.
Реалтайм бывает разный.
Современные Windows и Linux на грамотно построенной аппаратуре и соотв. драйверном и прикладном ПО способны обеспечить реакцию в единицы микросекунд запросто.
ЕМ>В основном тормозят кривые драйверы (в том числе родные) и чрезмерно раздутый код ядра.
Приличная часть кода ядра может и не использоваться вовсе, а в Linux лишнее можно легко выключить из сборки.
Ведь ты ж не будешь строить реалтаймовую систему как "просто еще одну программу" на десктопе общего назначения?
Зачем запускать десятки ненужных процессов?
V>>в виндах отродясь был realtime-приоритет, для linux есть соотв. патчи. ЕМ>Это всего лишь наивысший приоритет user-mode кода. От тормозов в ядре он спасти не может.
Процессоры сегодня многоядерные, поэтому, если с драйвером нет взаимных блокировок ресурсов и прикладной поток исполняется в другом ядре чем то, которое обслуживает прерывание, то прикладной процесс с наивысшим приоритетом будет всегда оперативно получать тики проца.
Там всей разницы, что ожидающий на семафоре или HEVENT такой поток получает тики проца в Windows сразу же при установке примитива сигнализации, а в Linux такие потоки получали тики проца через стандартный решедуллинг раз в 1/1000 сек, почему Linux и не считалась системой реального времени. Но есть патчи, которые заставляют решедулить потоки при установке из ядра примитивов сигнализации, т.е. которые передают управление нужному потоку сразу — у каждого примитива сигнализации есть список ожидающих его потоков. На autoreset HEVENT обычно ожидает один поток, на семафоре могут ожидать несколько потоков, например, несколько прикладных потоков с наивысшим приоритетом раскиданы по физическим ядрам и обрабатывают поступающие данные в режиме СМО.
V>>не стоит создавать взаимные блокировки ресурсов у драйвера и прикладной части, стоит использовать lock-free техники. ЕМ>Стоит, но кто бы это делал в той же винде...
Там это делали отродясь, по крайней мере в дровах от самой MS.
V>>прикладной код может целиком жить в драйвере, хотя в этом случае писать придётся на Си или на сильно урезанном С++ — без исключений/RAII, без динамической инициализации глобальных объектов, без RTTI и, возможно, без сохранения плавающих регистров м/у прерываниями, т.е., ЕМ>RAII не требует ничего, кроме поддержки конструкторов/деструкторов, это реализовано везде.
RAII требует реакции на исключения.
Но, я мог здесь и поторопиться в рассуждениях, бо, действительно, в отсутствии исключений, дело только за вызовами деструкторов по выходу из scope.
ЕМ>А что такое "динамическая инициализация глобальных объектов"?
Это когда у глобальных/статических переменных вызывается конструктор и в конце работы модуля деструктор.
Здравствуйте, Евгений Музыченко, Вы писали:
V>>не стоит создавать взаимные блокировки ресурсов у драйвера и прикладной части, стоит использовать lock-free техники. ЕМ>Стоит, но кто бы это делал в той же винде...
Сложно протестировать и\или провалидировать подобный код. Если речь о ядре.
V>>подавляющее большинство плюсовых библиотек использовать будет невозможно. ЕМ>Их уже из-за исключений невозможно использовать.
Здравствуйте, vdimas, Вы писали:
ЕМ>>в Windows аппаратные прерывания — один из последних факторов, влияющих на реактивность процессов.
V>Это от драйвера зависит.
Сами по себе аппаратные прерывания и общий механизм их обработки в ОС не зависят от драйверов. А уж когда дошло до драйвера, может случиться все, что угодно.
V>Современные Windows и Linux на грамотно построенной аппаратуре и соотв. драйверном и прикладном ПО способны обеспечить реакцию в единицы микросекунд запросто.
Я в курсе. Реакция за микросекунды — нормально, сотни тысяч прерываний в секунду для системы общего назначения — ненормально.
ЕМ>>В основном тормозят кривые драйверы (в том числе родные) и чрезмерно раздутый код ядра.
V>Приличная часть кода ядра может и не использоваться вовсе
В современной винде с этим все хуже и хуже с каждой очередной версией, особенно после введения в ядро гипервизора.
V>Ведь ты ж не будешь строить реалтаймовую систему как "просто еще одну программу" на десктопе общего назначения?
Почему бы и нет, если требования разумны? Вполне логично было бы, например, использовать "десктоп общего назначения" для воспроизведения музыки и показа картинок в клубе. Но та же винда без специального допиливания и жесткого контроля всего софта имеет свойство запинаться в случайные моменты времени.
V>>>в виндах отродясь был realtime-приоритет, для linux есть соотв. патчи. ЕМ>>Это всего лишь наивысший приоритет user-mode кода. От тормозов в ядре он спасти не может.
V>Процессоры сегодня многоядерные, поэтому, если с драйвером нет взаимных блокировок ресурсов и прикладной поток исполняется в другом ядре чем то, которое обслуживает прерывание, то прикладной процесс с наивысшим приоритетом будет всегда оперативно получать тики проца.
Если умудрится обходиться без общих ресурсов системы (например, файлов).
V>Там всей разницы, что ожидающий на семафоре или HEVENT такой поток получает тики проца в Windows сразу же при установке примитива сигнализации
Не "получает", а может получать, и не "тики проца", а временное повышение приоритета, а до тиков проца в этот момент еще очень далеко.
V>>>стоит использовать lock-free техники. ЕМ>>Стоит, но кто бы это делал в той же винде...
V>Там это делали отродясь, по крайней мере в дровах от самой MS.
Э-э-э... В каких именно драйверах от MS Вы видели "lock-free техники"? Может, конечно, и есть отдельные примеры, которых я не видел, но "отродясь" там все тупо на спинлоках, мьютексах и событиях.
V>RAII требует реакции на исключения.
Сам по себе — не требует, и никогда не требовал, он вообще ничего не знает о существовании исключений.
V>дело только за вызовами деструкторов по выходу из scope.
Именно.
ЕМ>>А что такое "динамическая инициализация глобальных объектов"?
V>Это когда у глобальных/статических переменных вызывается конструктор и в конце работы модуля деструктор.
Это ж всегда называлось статической инициализацией, ибо программа в этом не участвует, за нее это делает CRT. Тоже элементарно реализуется в ядерном коде, я такое давно использую.
Здравствуйте, Sharov, Вы писали:
S>Сложно протестировать и\или провалидировать подобный код. Если речь о ядре.
Почему сложно? Любые техники синхронизации тестируются одинаково — запускается несколько параллельных потоков, которые конкурируют между собой за ресурсы, попутно проверяя корректность работы примитивов, и гоняется какое-то время.
V>>>подавляющее большинство плюсовых библиотек использовать будет невозможно. ЕМ>>Их уже из-за исключений невозможно использовать.
S>А при чем тут исключения?
Большинство плюсовых библиотек без исключений не живет, иначе их не считали бы "истинно плюсовыми".
Здравствуйте, Евгений Музыченко, Вы писали:
S>>Сложно протестировать и\или провалидировать подобный код. Если речь о ядре. ЕМ>Почему сложно? Любые техники синхронизации тестируются одинаково — запускается несколько параллельных потоков, которые конкурируют между собой за ресурсы, попутно проверяя корректность работы примитивов, и гоняется какое-то время.
Речь о lock-free алгоритмах, где нету никаких примитивов синхроиназии, используются cas инструкции,
т.е. атомарные. Кажется, что с примитвом протестировать и проверить прощее, а вот без уже
проблематично. Ну и речь о ядре, там своя специфика. Наверное.
S>>А при чем тут исключения? ЕМ>Большинство плюсовых библиотек без исключений не живет, иначе их не считали бы "истинно плюсовыми".
А какая проблема с исключениями в rt системах(или ядре) как таковых?
Здравствуйте, Евгений Музыченко, Вы писали:
П>>Ничего там не вылизывалось, ставил на древнюю систему самую обычную древнюю XPшку, по сети закидывал файлы с жи кодом
ЕМ>Повезло, бывает.
Ну, вообще-то этим мачем дофига народу пользуется. Всем везёт?
Здравствуйте, andyp, Вы писали:
A>Если сможешь доказать, что прога + ос (т.е. все целиком) ВСЕГДА реагирует на внешние раздражители за некоторое наперед известное время, то система будет системой реального времени, отчего ж нет.
А какой она в этом случае будет, soft... или hard...?
Пока не доказано, не является?
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, tapatoon, Вы писали:
T>Каждая апи ОС принимает параметр максимального времени исполнения, по прошествии которого гарантированно возвращается результат операции или таймаут
Здравствуйте, Sharov, Вы писали:
S>Речь о lock-free алгоритмах, где нету никаких примитивов синхроиназии, используются cas инструкции,
Я в курсе. Эти команды и есть примитивы.
S>Кажется, что с примитвом протестировать и проверить прощее, а вот без уже проблематично.
Какая разница-то, если все тупо сводится к массированному конкурентному использованию примитивов, какими бы они ни были?
S>речь о ядре, там своя специфика. Наверное.
Там всей специфики — нельзя [слишком долго] ждать в состояниях, в которых недоступно переключение контекста, а для lock-free ожидания не требуется.
S>А какая проблема с исключениями в rt системах(или ядре) как таковых?
С обычными исключениями — никакой, а с плюсовыми вся проблема в том, что этот громоздкий и уродливый механизм попросту не хотят тащить в ядро, и правильно делают.
Здравствуйте, пффф, Вы писали:
П>вообще-то этим мачем дофига народу пользуется. Всем везёт?
Всем везти никак не может. Либо Вы недостаточно информированы, либо там инструкция требует определенных телодвижений для получения состояния системы, которое у Вас (и еще кого-то, но далеко не у всех) получилось случайно.
Здравствуйте, Философ, Вы писали:
Ф>есть там какая-нибудь гарантия, что аудио никогда не будет заикаться, а видео не будет пропускать кадры?
Абсолютной гарантии нигде нет. Но в мало-мальски приличной RT-системе вероятность заикания/пропуска примерно такая же, как и появления дефектного блока на диске, порчи данных в памяти и т.п. То есть, она ненулевая, но, во-первых, пренебрежимо мала на фоне длительности успешной работы, а во-вторых, такая ситуация рассматривается, как отказ/нарушение работы, а не как вполне штатная, хоть и досадная, ситуация.
Здравствуйте, Евгений Музыченко, Вы писали:
Ф>>есть там какая-нибудь гарантия, что аудио никогда не будет заикаться, а видео не будет пропускать кадры? ЕМ>Абсолютной гарантии нигде нет. Но в мало-мальски приличной RT-системе...
Данная ветка про Линукс. Я у него про Линукс спрашивал.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Почему сложно? Любые техники синхронизации тестируются одинаково — запускается несколько параллельных потоков, которые конкурируют между собой за ресурсы, попутно проверяя корректность работы примитивов, и гоняется какое-то время.
Фигня. У меня, где-то в моих завалах лежит пример кода, в котором ошибка на i7-6700K воспроизводилась один раз на примерно 300К итераций, а на i9-11900kf не воспроизводится. Я догадываюсь, что воспроизведётся рано или поздно, но ни разу не дожидался воспроизведения.
Гонять какое-то время — явно плохой способ.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Sharov, Вы писали:
S>Речь о lock-free алгоритмах, где нету никаких примитивов синхроиназии, используются cas инструкции, S>т.е. атомарные.
Вот кто-нибудь бы ещё в мануалы к процессорам заглядывал, например в интеловский, где английским по белому написано про эти инструкции, что чтобы они были атомарными, нужно использовать LOCK prefix — оно lock на шину выставляет.
Вот, например CMPXCHG
This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. 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 destination operand is written back if the comparison fails; otherwise, the source operand is
written into the destination. (The processor never produces a locked read without also producing a locked write.)
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Евгений Музыченко, Вы писали:
S>>Речь о lock-free алгоритмах, где нету никаких примитивов синхроиназии, используются cas инструкции, ЕМ>Я в курсе. Эти команды и есть примитивы.
Не понял, одно дело некий объект (мьютекс), а другое дело инструкция "атомарно считать и обновить".
Можно притив захватить какой-нибудь соотв. инсрукцией, например. Но это не одно и тоже.
S>>Кажется, что с примитвом протестировать и проверить прощее, а вот без уже проблематично. ЕМ>Какая разница-то, если все тупо сводится к массированному конкурентному использованию примитивов, какими бы они ни были?
Мне казалось, что lock-free алгоритмы не предполагают примитивов.
S>>речь о ядре, там своя специфика. Наверное. ЕМ>Там всей специфики — нельзя [слишком долго] ждать в состояниях, в которых недоступно переключение контекста, а для lock-free ожидания не требуется.
Тут согласен, поток по идее всегда что-то делает, а не ждет чего-то. Точнее ждет активно.
Здравствуйте, Евгений Музыченко, Вы писали:
П>>вообще-то этим мачем дофига народу пользуется. Всем везёт?
ЕМ>Всем везти никак не может. Либо Вы недостаточно информированы, либо там инструкция требует определенных телодвижений для получения состояния системы, которое у Вас (и еще кого-то, но далеко не у всех) получилось случайно.
Я хорошо вопрос изучал. Нет ни инструкции по настройке системы под это ПО, ни жалоб тех, у кого оно не работает. Ну, то есть, много вопросов, как настроить входные/выходные пины LPT-порта, что и как с платами совместимых с ним контроллеров, и тд и тп. Про настройку WinXP ничего нет. Единственное, что было известно на тот момент — это то, что Mach3 ставит в систему какой-то свой драйвер, и по этой причине не совместима с вистой и семёркой.
Здравствуйте, Философ, Вы писали:
S>>Речь о lock-free алгоритмах, где нету никаких примитивов синхроиназии, используются cas инструкции, S>>т.е. атомарные. Ф>Вот кто-нибудь бы ещё в мануалы к процессорам заглядывал, например в интеловский, где английским по белому написано про эти инструкции, что чтобы они были атомарными, нужно использовать LOCK prefix — оно lock на шину выставляет. Ф>Вот, например CMPXCHG Ф>
Ф>This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. 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 destination operand is written back if the comparison fails; otherwise, the source operand is
Ф>written into the destination. (The processor never produces a locked read without also producing a locked write.)
Благодарю, но это уже детали реализации. Я имел в виду под примитивами структуры данных, которые находятся в памяти,
типа мьюетксов\семафоров\мониторов и чего только не. Соотв. из-за них всяческие задержки при переключении контекстов
и т.п., что в эпоху многоядерности не очень чтобы очень. Сделали free-lock, точнее, наверное, переоткрыли.
Цитата выше хороша, но это делати реализации этих самых free-lock инструкций.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Почему бы и нет, если требования разумны? Вполне логично было бы, например, использовать "десктоп общего назначения" для воспроизведения музыки и показа картинок в клубе.
Это не тот реалтайм.
Через буферирование до 1-2 сек требования к "реалтаймовости" снижаются до примерно этих значений. ))
ЕМ>Но та же винда без специального допиливания и жесткого контроля всего софта имеет свойство запинаться в случайные моменты времени.
Это только обновления, плановое обслуживание дисков (если HD) и проверка на вирусы/трояны.
Всё это отключается через политики простым скриптом.
ЕМ>Если умудрится обходиться без общих ресурсов системы (например, файлов).
Ну, когда разговор о реалтаймовых системах, то обычно подразумевают малый порядок времени отклика...
Какие там уже файлы? ))
Шаренная память, конечно.
V>>Там всей разницы, что ожидающий на семафоре или HEVENT такой поток получает тики проца в Windows сразу же при установке примитива сигнализации ЕМ>Не "получает", а может получать
Не, в случае наивысшего приоритета потока — получает железно 100%-но! ))
ЕМ>и не "тики проца", а временное повышение приоритета, а до тиков проца в этот момент еще очень далеко.
Если проц не был занят другим потоком с этим наивысшим приоритетом, то без разговоров привязанный через affinity проц тут же переключается на ожидающий на примитиве сигнализации реалтаймовый поток. Стоимость переключения контекста — чуть более сотни наносекунд на современном железе, это примерно нижний предел отзывчивости такой схемы.
Я с этим одно время плотно экспериментировал с дровами ASIO, добивался задержки обработки звука 2 мс, где комп представлял из себя гитарную самописную примочку.
V>>>>стоит использовать lock-free техники. ЕМ>>>Стоит, но кто бы это делал в той же винде... V>>Там это делали отродясь, по крайней мере в дровах от самой MS. ЕМ>Э-э-э... В каких именно драйверах от MS Вы видели "lock-free техники"? Может, конечно, и есть отдельные примеры, которых я не видел, но "отродясь" там все тупо на спинлоках, мьютексах и событиях.
Там lock-free очереди.
Причём, что забавно, примерно такие же (вернее, почти в точности такие же) очереди я "изобрел" и вылизал в нулевые, пока MS однажды не открыла исходники своей библиотеки для построения межпотоковой обработки данных. Причём, все годы до этого я несколько переживал насчёт своей схемы (многократно мысленно и в тестах трассировал, там достаточно много было тонкостей), но, увидев практически один-в-один реализацию, вздохнул с облегчением.
В общем, в этой схеме при высокой нагрузке примитив сигнализации практически не дергается (или не дёргается вовсе).
Он дёргается только при низкой нагрузке, т.е. когда система находится большую часть времени в режиме ожидания.
В любом случае, не проблема дёрнуть HEVENT или семафор из разных потоков, бо там lock-free в цикле унутре ядра на этих примитивах.
Проблема может быть, например, с мьютексом или другими ресурсами, доступ к которым организован как исключительный.
Так вот, этого исключительного одновременного доступа из драйвера и из юзерского кода быть не должно.
V>>RAII требует реакции на исключения. ЕМ>Сам по себе — не требует, и никогда не требовал, он вообще ничего не знает о существовании исключений.
Дык, в случае исключений вызывается таблица деструкторов на каждом уровне исключений.
V>>дело только за вызовами деструкторов по выходу из scope.
ЕМ>Именно.
ЕМ>>>А что такое "динамическая инициализация глобальных объектов"? V>>Это когда у глобальных/статических переменных вызывается конструктор и в конце работы модуля деструктор. ЕМ>Это ж всегда называлось статической инициализацией
Фаза статической инициализации — это загрузка модуля загрузчиком ОС.
Это инициализация глобальных переменных константами времени компиляции или константами времени загрузки модуля (например, физическими адресами ф-ий и глобальных переменных).
ЕМ>ибо программа в этом не участвует, за нее это делает CRT.
Эта часть называется динамической инициализацией, т.к. уже исполняется пользовательский код (тела конструкторов).
В фазе статической инициализации пользовательский код не исполняется.
ЕМ>Тоже элементарно реализуется в ядерном коде, я такое давно использую.
Это ты линковался с подменой каких-нить конкретных кишок CRT конкретного компилятора своими хелперами?
Или речь о самописной подсистеме, эмулирующей происходящее, но заставляющей оформлять глобальные переменные неким особым образом (т.е. не обеспечивающей гарантии языка)?
Второе я делал банально для TLS-объектов, бо в прошлых стандартах оно не работало. ))
Здравствуйте, Sharov, Вы писали:
S>Не понял, одно дело некий объект (мьютекс), а другое дело инструкция "атомарно считать и обновить".
Сама по себе команда не реализует никакого механизма синхронизации — они все строятся на основе атомарных команд.
S>Мне казалось, что lock-free алгоритмы не предполагают примитивов.
"Примитивом" нередко называютвообще любой механизм/алгоритм, достаточно простой на фоне программы, которая его использует, это не обязательно готовая функция ОС.
Здравствуйте, пффф, Вы писали:
П>много вопросов, как настроить входные/выходные пины LPT-порта
То есть, Вас никогда не удивляло, что для стабильной работы программаторов, напрямую выводящих сигналы на линии COM/LPT, в любой системе с многозадачностью, виртуальной памятью и прочими блэкджеками, часто требуются пляски с бубном, а Mach3 волшебным образом обходится без них?
П>Mach3 ставит в систему какой-то свой драйвер, и по этой причине не совместима с вистой и семёркой.
Вот Вам и ответ. Скорее всего, установкой драйвера, который патчит ядро, перехватывает функции ОС и т.п., дело не ограничивается — наверняка и установщик модифицирует параметры загрузки/работы ядра, планировщика, виртуальной памяти и прочего.
Здравствуйте, Евгений Музыченко, Вы писали:
П>>Mach3 ставит в систему какой-то свой драйвер, и по этой причине не совместима с вистой и семёркой.
ЕМ>Вот Вам и ответ. Скорее всего, установкой драйвера, который патчит ядро, перехватывает функции ОС и т.п., дело не ограничивается — наверняка и установщик модифицирует параметры загрузки/работы ядра, планировщика, виртуальной памяти и прочего.
Ну и отлично — легким движением руки брюки превращаются...простой установкой своего драйвера ОС становится вполне себе риалтаймовой
Здравствуйте, vdimas, Вы писали:
ЕМ>>использовать "десктоп общего назначения" для воспроизведения музыки и показа картинок в клубе.
V>Это не тот реалтайм.
Если тупо проигрывать MP3 и отображать картинки из файлов — да. Но в клубах часто используют диджейские станции, которые смешивают разные звуки, добавляют звуковые эффекты в музыку и голос, визуальные — в изображения, и т.п. Там очень плотные вычисления, и задержки даже в десяток миллисекунд могут быть слышны.
ЕМ>>Но та же винда без специального допиливания и жесткого контроля всего софта имеет свойство запинаться в случайные моменты времени.
V>Это только обновления, плановое обслуживание дисков (если HD) и проверка на вирусы/трояны.
Не, это может происходить при подключении/отключении устройств, при обработке потоков не слишком правильными видеодрайверами, и в ряде других ситуаций.
V>Всё это отключается через политики простым скриптом.
Неважно, насколько просто это делается — важно то, что это приходится знать и делать.
V>Ну, когда разговор о реалтаймовых системах, то обычно подразумевают малый порядок времени отклика... V>Какие там уже файлы? ))
Если время доступа к файлу технически укладывается в требуемое время отклика, ничто не мешает использовать файлы в системе хоть жесткого реального времени. Лишь бы не тормозило сверх меры.
V>Шаренная память, конечно.
Да никакой разницы. Это все компоненты системы, имеющие каждая собственные рамки. Медленное ОЗУ ничем не лучше медленного диска.
V>Не, в случае наивысшего приоритета потока — получает железно 100%-но! ))
Мамой клянетесь?
ЕМ>>и не "тики проца", а временное повышение приоритета, а до тиков проца в этот момент еще очень далеко.
V>Если проц не был занят другим потоком с этим наивысшим приоритетом, то без разговоров привязанный через affinity проц тут же переключается на ожидающий на примитиве сигнализации реалтаймовый поток. Стоимость переключения контекста — чуть более сотни наносекунд на современном железе, это примерно нижний предел отзывчивости такой схемы.
Угу, только столь радужная картина будет только в случае, когда нужный процессор в это время висит в аппаратном ожидании. Если на нем вдруг выполняется обработчик обычного и/или отложенного прерывания, то до переключения контекста дойдет лишь после того, как все эти обработчики завершатся. А время их выполнения далеко не всегда ничтожно мало, поскольку их все чаще пишут из соображений "компилятор все оптимизирует", "процессор все разрулит", "и вообще, кого волнует лишняя сотня микросекунд".
V>Я с этим одно время плотно экспериментировал
А я с этим работаю уже больше двадцати лет. И хорошо вижу, где какие задержки.
V>с дровами ASIO
Это вообще чистый код пользовательского режима, работающий поверх любых ядерных средств, и довольно примитивный, неудобный и кривой. Но, поскольку этот интерфейс принято поддерживать в любых "профессиональных" устройствах, в соответствующей среде он считается верхом совершенства и эффективности, даже если работает через какой-нибудь тормозной драйвер ядра.
V>добивался задержки обработки звука 2 мс
Если железо позволяет, и драйвер хороший, то через KS (через который чаще всего и работает ASIO) можно и до 500-700 мкс допинать. Но с приседаниями.
V>Там lock-free очереди.
В каких именно драйверах ядра Вы их видели, и для чего они там?
V>исключительного одновременного доступа из драйвера и из юзерского кода быть не должно.
Не должно, но не всегда получается их корректно развести без ограничения функциональности.
V>Это ты линковался с подменой каких-нить конкретных кишок CRT конкретного компилятора своими хелперами?
Ага. У меня вообще свой простейший CRT, я пользуюсь только "независимыми" библиотечными функциями, которым не нужна определенная среда.
Здравствуйте, ArtDenis, Вы писали:
AD>Лично для меня realtime в ОС в первую очередь означает гарантированное время, от прихода события, до момента, когда начали выполняться первые инструкции обработчика события. AD>Например, устройство по DMA заполнило буфер и вызвало аппаратное событие, которое в свою очередь вызвало прерывание, внутри которого ОС было уведомлено, что данные готовы, после чего (уже не в прерывании, а в задаче ОС в пользовательском коде) начали обрабатываться данные. В данном случае, если от момента, когда железо вызвало событие, до момента обработки данных в пользовательском коде, промежуток детерминирован, то это realtime, если не детерминирован и зависит от фазы Луны, то не realtime
Это необходимое условие, но не достаточное. Есть и другие подобные места в системе.
Здравствуйте, Евгений Музыченко, Вы писали:
V>>Не, в случае наивысшего приоритета потока — получает железно 100%-но! )) ЕМ>Мамой клянетесь?
Обычные тесты из миллиардов итераций в течении десятков минут и плотной работы других приложений, в т.ч. с HD-дисками, что классически вызывает торможения порой даже мышки.
Есть два реалтаймовых потока, разнесённых через affinity по разным ядрам, кроме нулевого.
Обмениваются сигналом с одного семафора поочерёдно, замеряется время реакции.
Укладывалось до менее микросекунды, вычти еще отсюда стоимость вызова QPC и вычти стоимость принудительного вытеснения потока из-за захода в блокирующее ожидание.
На технике из 2009-го укладывалось в полторы микросекунды.
И ни разу не пролабало.
Да, никакие мультимедия приложения не работали, бо в них тоже порой бывают реалтаймовые приоритеты, т.е. гарантировать наивысший и исключительный такой приоритет для тестовых потоков было бы нельзя.
ЕМ>>>и не "тики проца", а временное повышение приоритета, а до тиков проца в этот момент еще очень далеко. V>>Если проц не был занят другим потоком с этим наивысшим приоритетом, то без разговоров привязанный через affinity проц тут же переключается на ожидающий на примитиве сигнализации реалтаймовый поток. Стоимость переключения контекста — чуть более сотни наносекунд на современном железе, это примерно нижний предел отзывчивости такой схемы. ЕМ>Угу, только столь радужная картина будет только в случае, когда нужный процессор в это время висит в аппаратном ожидании.
Не процессор, а ядро, у меня в непосредственном распоряжении были только однопроцессорные машинки.
И откуда там аппаратное ожидание на семафоре?
Блокирующее ожидание на семафоре или HEVENT всегда приводит к вытеснению потока и постановке ожидающего потока в сортированную по приоритетам очередь ожидающих потоков на примитиве синхронизации.
Т.е., в момент установки семафора ОС проверяет очередь ожидающих потоков и их приоритет (в сортированной очереди проверяется только голова списка), затем, в случае привязки affinity, всё происходит достаточно прямолинейно — проверяется текущий поток только указанного ядра и, если приоритет исполняющегося потока оказался ниже приоритета ожидающего потока (да, ты прав, после некоторого ожидания "виртуальный" приоритет ожидающего потока поднимается в этих расчётах, но в случае реалтаймового потока мы уже имеем наивысший приоритет из всех возможных), затем тому ядру посылается соотв. софтовое прерывание для переключения контекста исполнения на другой софтовый поток.
Выглядит всё это достаточно дорогостояще, но в сотни наносекунд на современном железе укладывается.
Понятно, что можно использовать spin-wait техники и или есть еще техники для межпоточных очередей (через доп. interlocked trigger), чтобы не обращаться лишний раз к примитиву синхронизации уровня ядра и не тратить тики процессорных ядер на достаточно дорогостоящий решедуллинг с переключением контекста.
ЕМ>Если на нем вдруг выполняется обработчик обычного и/или отложенного прерывания
На 3-м пинг-понге, когда каждый раз говорилось, что потоки насильно привязываются к ядрам, не участвующем в обработке аппаратных прерываний, а только реагирующих на сигналы (программные прерывания), это уже как спекуляция. ))
ЕМ>то до переключения контекста дойдет лишь после того, как все эти обработчики завершатся.
Да там единственный непрерываемый сигнал софтовый сигнал — это смена текущего контекста исполнения.
Т.е. плюс-минус до сотни наносекунд примерно потенциальное "дрожание фронта". ))
И то, событие достаточно редкое по меркам систем, где рассуждают о реалтайме.
ЕМ>А время их выполнения далеко не всегда ничтожно мало, поскольку их все чаще пишут из соображений "компилятор все оптимизирует", "процессор все разрулит", "и вообще, кого волнует лишняя сотня микросекунд".
Большинство софтовых сигналов могут прерваны более приоритетными сигналами — я в самом первом сообщении ветки уже упомянул это, что такие обработчики не несут с собой нерешаемой проблемы.
для "длинных" софтовых прерываний в этих ОС никогда не было проблем одновременной их обработки.
"Длинными прерываниями" называют софтовые прерывания, чьи обработчики могут быть достаточно тяжеловесными.
V>>Я с этим одно время плотно экспериментировал
ЕМ>А я с этим работаю уже больше двадцати лет. И хорошо вижу, где какие задержки.
V>>с дровами ASIO ЕМ>Это вообще чистый код пользовательского режима, работающий поверх любых ядерных средств
Верно, ответная часть работает в пользовательском режиме.
ASIO — это своеобразная "дыра" на дравейрный уровень аудиокарты, где с этой дырой общаешься в стримовом режиме — через порции данных.
В том числе есть чисто софтовая эмуляция интерфейса https://asio4all.org/, удобная для разработки и отладки.
Но профессиональные аудиокарты, в т.ч. внешние USB 3.0 уже идут со своими дровами ASIO, с чем я тоже одно время несколько лет плотно работал. ))
ЕМ>и довольно примитивный, неудобный и кривой.
ХЗ, насчёт примитивный.
В этом и был смысл, наверно, чтобы миновать всевозможные этапы конвейеров аудиокарт и соотв. их драйверов, т.е. стрим идёт мимо микшеров, мимо посаженных эффектов картейки (шумоподавление, эхо и т.д.), мимо вообще всего тупо на выход или тупо со входа.
ЕМ>Но, поскольку этот интерфейс принято поддерживать в любых "профессиональных" устройствах, в соответствующей среде он считается верхом совершенства и эффективности, даже если работает через какой-нибудь тормозной драйвер ядра.
Дык, в случае внешней USB-картейки принципиально нет возможности реализовать эту схему иначе, чем через ядерный драйвер.
(Поправь, если я не прав)
V>>добивался задержки обработки звука 2 мс ЕМ>Если железо позволяет, и драйвер хороший, то через KS (через который чаще всего и работает ASIO) можно и до 500-700 мкс допинать. Но с приседаниями.
Это на полный круг со своими эффектами звука уже.
"Без приседаний" нижний предел был в районе 8-10 ms.
V>>Там lock-free очереди. ЕМ>В каких именно драйверах ядра Вы их видели, и для чего они там?
Это в открытом однажды их фреймворке для эффективной многопоточной обработки данных.
Их реализация на Си, моя "типизированная" с шаблонами — на С++.
Но суть происходящего была идентична, что меня и улыбнуло, и успокоило. ))
V>>исключительного одновременного доступа из драйвера и из юзерского кода быть не должно. ЕМ>Не должно, но не всегда получается их корректно развести без ограничения функциональности.
Прям уж не всегда?
Мне как раз любопытны такие задачи, бо много возился с задачами как раз избегания столкновения потоков.
V>>Это ты линковался с подменой каких-нить конкретных кишок CRT конкретного компилятора своими хелперами? ЕМ>Ага. У меня вообще свой простейший CRT, я пользуюсь только "независимыми" библиотечными функциями, которым не нужна определенная среда.
Мне вообще странно, почему подобное не идёт изкаробки. ))
Сам я тоже когда-то давно обнаружил, что придётся разбираться с кишками CRT компилятора и пилить под себя нечто подобное, бо на чистых сях писать, таки, ощутимая боль. ))
Но т.к. довольно много не писал в этой области, то время на это решил не тратить, а потом полностью ушёл в юзверскую разработку.
Здравствуйте, vdimas, Вы писали:
V>Обычные тесты из миллиардов итераций в течении десятков минут и плотной работы других приложений, в т.ч. с HD-дисками, что классически вызывает торможения порой даже мышки.
Как раз плотная работа HDD должна вызывать меньше торможений (если в коде нет косяков), чем столь же плотная работа SSD. Драйвер заряжает передачу по DMA и сразу возвращает управление. А вот некоторые драйверы SSD, судя по всему, "оптимизируют" не слишком длинные операции, не возвращая управления до их завершения, чтобы получить более высокие результаты в тестах за счет ресурсов процессора.
V>На технике из 2009-го укладывалось в полторы микросекунды.
Сколько сочетаний железа/ОС Вы таким образом тестировали, и какие телодвижения предшествовали получению таких результатов?
По моему опыту, получение подобной стабильной реактивности "искаропки" — скорее исключение, чем правило. Как минимум, требуется настройка железа и винды, и даже после этого не всегда удается получить стабильную реактивность.
V>Не процессор, а ядро
В этом контексте нет никакой разницы, терминология допускает. "Логический процессор", если уж совсем точно.
V>И откуда там аппаратное ожидание на семафоре?
Ну а что еще делать процессору/ядру, когда у него нет кода, готового к исполнению? Коль уж Вы упоминаете affinity, назначенный тестовому потоку, то возникает логичное предположение, что все остальные процессы/потоки на данный процессор/ядро не допускаются, и на нем исполняется только служебный код ОС (привязанные прерывания, DPC и прочее). Иначе нет почти никакого смысла в привязывании потока к определенным ядрам — большее значение имеет отвязывание его от наиболее загруженных ядер (того же нулевого).
V>когда каждый раз говорилось, что потоки насильно привязываются к ядрам, не участвующем в обработке аппаратных прерываний
А Вы проверяли, что эти ядра действительно не участвуют? Ну и не забывайте про DPC affinity — это вполне себе годный способ распределения нагрузки. Смотрели распределение DPC по ядрам?
V>только реагирующих на сигналы (программные прерывания)
Что именно Вы называете "программными прерываниями"? Чтобы известить другие процессоры/ядра о событии, используется аппаратное IPI, оно не бесплатное.
ЕМ>>то до переключения контекста дойдет лишь после того, как все эти обработчики завершатся.
V>Да там единственный непрерываемый сигнал софтовый сигнал — это смена текущего контекста исполнения.
Так на каком основании Вы предполагаете, что нужное ядро всегда будет готово к переключению контекста?
V>Большинство софтовых сигналов могут прерваны более приоритетными сигналами
Что Вы называете "сигналами" применительно к Windows? Документация MS по ядру Windows использует только глагол to signal, и прилагательное signaled.
V>"Длинными прерываниями" называют софтовые прерывания, чьи обработчики могут быть достаточно тяжеловесными.
Где именно они так называются? Если Вы об общей теории прерываний, то она допускает различные реализации. А конкретно в Windows термин interrupt используется только в отношении аппаратного прерывания. "Долгая" обработка реализуется через DPC, к ним существительное interrupt не применяется. У DPC есть приоритеты, но они влияют только на размещение в очереди. Если на ядре/процессоре начал выполнение обработчик DPC, то прервать его может только аппаратное прерывание, после завершения которого он продолжит работу, принудительно вытеснить его другим DPC или потоком невозможно.
V>ASIO — это своеобразная "дыра" на дравейрный уровень аудиокарты, где с этой дырой общаешься в стримовом режиме — через порции данных.
Знаю, я делал и драйверы ASIO, и клиенты для них. Редкостное убожество. Даже в 90-х оно годилось максимум в качестве временного наколенного решения, но тащить его тридцать лет — знатное извращение.
V>Но профессиональные аудиокарты, в т.ч. внешние USB 3.0 уже идут со своими дровами ASIO
За редким исключением, там нет никаких особых "дров ASIO". Есть общий драйвер WDM/KS, а прилагаемая ASIO DLL работает либо через сам KS (как ASIO4ALL), либо через специальные функции ядерного драйвера, чтоб не заморачиваться с KS-протоколами.
V>В этом и был смысл, наверно, чтобы миновать всевозможные этапы конвейеров аудиокарт и соотв. их драйверов, т.е. стрим идёт мимо микшеров, мимо посаженных эффектов картейки (шумоподавление, эхо и т.д.), мимо вообще всего тупо на выход или тупо со входа.
В те времена, когда Steinberg его выкатила, не было никаких "конвейеров", "микшеров" и "эффектов". Тогда в винде просто был тормозной (и еще более примитивный) звуковой интерфейс, и любой драйвер ASIO работал с железом напрямую, вообще никак не контактируя с виндовой звуковой подсистемой. Но уже в Win2k это привели в порядок (KS был даже в Win98), и с тех пор для того, чтобы любить ASIO, нужно слепо верить в его крутизну и превосходство, иначе никак.
V>в случае внешней USB-картейки принципиально нет возможности реализовать эту схему иначе, чем через ядерный драйвер.
Для любого устройства иначе нельзя. Но необходимость прикручивать что-то сбоку отпала минимум 25 лет назад, а воз и ныне там.
V>"Без приседаний" нижний предел был в районе 8-10 мкс.
Микросекунд? Не верю. Может, милли-?
V>>>Там lock-free очереди. ЕМ>>В каких именно драйверах ядра Вы их видели, и для чего они там?
V>Это в открытом однажды их фреймворке для эффективной многопоточной обработки данных.
V>>>исключительного одновременного доступа из драйвера и из юзерского кода быть не должно. ЕМ>>Не должно, но не всегда получается их корректно развести без ограничения функциональности.
V>Прям уж не всегда?
Понятно, что в итоге-то "можно всегда", вопрос лишь в цене. Чтобы полностью исключить неопределенно долгое ожидание, инверсию приоритетов и прочие неприятности, нужно наворотить приличное количество кода, сильно потеряв в его прозрачности, расширяемости, удобстве поддержки. Поэтому на практике обычно исключают только самые вероятные затыки, а оставшиеся и создают те самые внезапные эффекты, что мешают "истинному реалтайму".
V>Мне как раз любопытны такие задачи, бо много возился с задачами как раз избегания столкновения потоков.
Когда все механизмы взаимодействия проектируются с нуля, и потом ничего не добавляется и не переделывается, то гораздо проще. Сложнее, когда нужно обеспечить синхронизацию с уже готовой библиотекой, использующей не самые удачные решения. В случае с виндой одной из таких библиотек является Port Class Driver для звуковых устройств. Его фреймворк заточен под то, чтоб минидрайвер мог написать даже весьма средний программист, поэтому с разведением возможных блокировок выходит очень грустно.
V>Мне вообще странно, почему подобное не идёт изкаробки. ))
Мне тоже странно, только многим ли оно надо? Большинство жрет, что дают, и просит еще.
Здравствуйте, Sharov, Вы писали:
S>Благодарю, но это уже детали реализации.
Без блокировок совсем не выходит, название "lock-free" — это обман.
S>Я имел в виду под примитивами структуры данных, которые находятся в памяти, S>типа мьюетксов\семафоров\мониторов и чего только не. Соотв. из-за них всяческие задержки при переключении контекстов S>и т.п., что в эпоху многоядерности не очень чтобы очень. Сделали free-lock, точнее, наверное, переоткрыли.
Проблема в переключении контекстов, в том что они долгие/медленные?
S>Цитата выше хороша, но это делати реализации этих самых free-lock инструкций.
Без блокировок совсем не выходит: другое ядро или другой процессор никаким другим способом не может синхронизировать работу с участком памяти, только блокировки, только сигнал LOCK. "lock-free" — это обман.
А это просто цитата из документации.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
S>>Я имел в виду под примитивами структуры данных, которые находятся в памяти, S>>типа мьюетксов\семафоров\мониторов и чего только не. Соотв. из-за них всяческие задержки при переключении контекстов S>>и т.п., что в эпоху многоядерности не очень чтобы очень. Сделали free-lock, точнее, наверное, переоткрыли. Ф>Проблема в переключении контекстов, в том что они долгие/медленные?
Типа того. Собственно, из-за этого в процессах появлись потоки. На уровне потоков все шустрее.
S>>Цитата выше хороша, но это делати реализации этих самых free-lock инструкций. Ф>Без блокировок совсем не выходит: другое ядро или другой процессор никаким другим способом не может синхронизировать работу с участком памяти, только блокировки, только сигнал LOCK. "lock-free" — это обман. Ф>А это просто цитата из документации.
Ну кстати, как оно на уровне процессов, а не потоков я не в курсе. Возможно дейстивительно поэтому в ядре
lock-free и не взлетает, т.к. на уровне процессов это крайне сложно, если вообще возможно.
Здравствуйте, Sharov, Вы писали:
S>Не понял, одно дело некий объект (мьютекс), а другое дело инструкция "атомарно считать и обновить".
Мьютекс именно такими инструкциями и обслуживается.
Сначала CAS на юзверском уровне, а если надо уйти в спячку — то CAS на ядерном семафоре, т.к. к мьютексу привязан (вернее, создаётся в ленивой CAS манере) семафор ОС, на котором можно ожидать готовности.
Но сам этот составной объект считается примитивом синхронизации, эдаким самодостаточным крипичиком с собственной функцией.
S>Мне казалось, что lock-free алгоритмы не предполагают примитивов.
Запросто предполагают.
Например, поток-читатель обнаруживает конец очереди, ну покрутил в spin-wait сколько-то там...
А потом надо уходить в честную спячку, освобождать ресурсы.
А из спячки как возвращаться? ))
Вот, на семафорах или событиях (или условных переменных, что наихудший вариант) и возвращаются.
S>Тут согласен, поток по идее всегда что-то делает, а не ждет чего-то. Точнее ждет активно.
Это оправдано только если нагрузка гарантирована.
А если нет, то так делать нельзя.
Здравствуйте, Философ, Вы писали:
Ф>Без блокировок совсем не выходит, название "lock-free" — это обман.
Всё-таки, взаимных блокировок не происходит, и это важно, бо взаимные блокировки в вытесняющей многозадачности — это злейшее зло, как выяснилось. ))
В кооперативной-однопроцессорной (одноядерной) многозадачности оно таким злом не было за невозможностью.
Вот там мьютексы были паиньками, что ими всё засрали нахрен в 80-е до 95-го, а потом как ужаснулись, когда пошло более одного ядра + вытесняющая многозадачность...
Ф>Проблема в переключении контекстов, в том что они долгие/медленные?
Да. Переключение контекстов заставляет перепрошивать внутренние таблицы виртуальной памяти, т.е. подтягивать эти таблицы, считай, в кеш 0-го уровня.
Помимо этого, переключение потока дорогое еще для потока, который вытесняют, потому что его ставят в очередь потоков, а это приоритетная очередь, операции в которой относительно затратны. А если поток вытесняется из-за блокирующего ожидания на примитиве синхронизации, то еще поток ставят в очередь к примитиву синхронизации.
Итого, который поток уходит — его дорого убирать из-за решедуллинга в очередях потоков.
Который поток ставят — его дорого ставить из-за переобновления таблиц виртуальной памяти.
Ф>Без блокировок совсем не выходит: другое ядро или другой процессор никаким другим способом не может синхронизировать работу с участком памяти, только блокировки, только сигнал LOCK. "lock-free" — это обман.
Никакого обмана. ))
CAS не блокирует ни один из потоков, выполняющих эту операцию над одним и тем же словом в памяти.
Просто гонку на CAS выиграет только один из потоков.
Т.е., lock-free гарантирует, что в каждый момент времени хотя бы один поток продвигается в своём исполнении.
Сравнить со столкновением потоков, где поток захватывает мьютексом или семафором ресурс, а потом ОС вытесняет этот поток и даёт тики потокам, которые этот ресурс в какой-то момент начинают ожидать. Да еще зачастую через spin-wait (как оно есть в мьютексах), а ждать там можно хоть до седьмого пришествия, только бесполезно. ))
Напротив, в lock-free алгоритмах ушедший в спячку поток никак не затормозит конкурирующие за ресурс потоки, а ровно наоборот.
Здравствуйте, vdimas, Вы писали:
Ф>>Без блокировок совсем не выходит, название "lock-free" — это обман.
V>Всё-таки, взаимных блокировок не происходит, и это важно... V>Вот там мьютексы были паиньками...
Я таки настаиваю, что название "lock-free" крайне кривое и не отражает сути вещей. Дело не в мьютексах потому что блокировка вполне может быть на spin-wait'е. Посмотри:
lock-free stack — классический пример, но тут мы видим модифицированный spin-wait. Цикл в методе Push равнозначен spin-wait'у и может быть им заменён.
Ф>>Проблема в переключении контекстов, в том что они долгие/медленные? V>Да. Переключение контекстов заставляет перепрошивать внутренние таблицы виртуальной памяти, т.е. подтягивать эти таблицы, считай, в кеш 0-го уровня. V>Помимо этого, переключение потока дорогое еще для потока, который вытесняют, потому что его ставят в очередь потоков, а это приоритетная очередь, операции в которой относительно затратны. А если поток вытесняется из-за блокирующего ожидания на примитиве синхронизации, то еще поток ставят в очередь к примитиву синхронизации.
Там было вставлено только затем, чтобы в цикл ожидания впихнуть инструкцию PAUSE. В шарпе такой вызов это наиболее простой способ. Это способ экономить электричество: эта инструкция — хинт процессору о том, что тут цикл активного ожидания, она специально для этого создавалась.
Однако о виндовом шедуллере всерьёз не задумывался. Мне всегда хватало твёрдого знания того, что поход в ядро — дорого.
Ф>>..."lock-free" — это обман. V>Никакого обмана. ))
Я про название.
V>Просто гонку на CAS выиграет только один из потоков.
Ужасная терминология.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Я таки настаиваю, что название "lock-free" крайне кривое и не отражает сути вещей. Дело не в мьютексах потому что блокировка вполне может быть на spin-wait'е. Посмотри:
Ф>
Ф>lock-free stack — классический пример, но тут мы видим модифицированный spin-wait. Цикл в методе Push равнозначен spin-wait'у и может быть им заменён.
Странно рассуждаешь. ))
В Spin-wait не происходит ничего, кроме удержания ресурсов процессора, а тут в очередь достоверно ставятся элементы, пока крутится цикл, просто они ставятся в других потоках. Т.е., блокировки очереди нет, именно поэтому lock-free.
И если конкурирующий поток уйдёт в спячку через вытеснение, то очередь не останется надолго заблокированной, как оно было бы при защите обычной очереди мьютексом, если бы перед вытеснением поток завладел бы ресурсом.
Ф>Я в общем-то знал, что поход в ядро — дорогое удовольствие, просто хотел намекнуть, что это необязательно: во многих случаях вполне можно обойтись spin-wait'ом.
Зачастую это плохая практика.
При нужной расстановке приоритетов потоков выгодней уходить в спячку, чем крутить 10 GOTO 10.
Тут банально стоит в тестах смотреть, куда и сколько тратиться больше бесполезных тиков — на лишние переключения контекстов или на 10 GOTO 10.
В моих тестах, если данные идут с задержками более ~5 микросекунд (5 миллионных секунды!), то выгодней уходить в спячку, освобождая ресурсы для других задач, чем крутить бесполезный spin-wait.
Например, в твоём цикле указан код писателя.
А что делать читателю в отсутствии данных?
Ну вот покрутил сколько-то spin-wait, дальше что? ))
Ф>Там было вставлено только затем, чтобы в цикл ожидания впихнуть инструкцию PAUSE. В шарпе такой вызов это наиболее простой способ. Это способ экономить электричество: эта инструкция — хинт процессору о том, что тут цикл активного ожидания, она специально для этого создавалась.
Это работает только в многопоточных ядрах, т.к. отдаёт ресурсы ядра процессору другому потоку (гипер-потоку в терминах Интел, например).
Если же ядра унутре однопоточные, то PAUSE не делает аж ничего, это аналог NOP.
Ф>>>..."lock-free" — это обман. V>>Никакого обмана. )) Ф>Я про название.
Я тоже.
См. пример своей очереди выше.
У тебя писатели не блокируют очередь взаимно, и читатели могу читать конкурентно (правда, там за раз можно безопасно забрать только всю накопленную очередь, а не один элемент, но это уже тонкости... зато по этой порции можно уже итерироваться без interlocked-операций)
V>>Просто гонку на CAS выиграет только один из потоков. Ф>Ужасная терминология.
Сорри, у нас много кальки с английского. ))
В данном случае "a thread that won the race".
В русской терминологии "состязание потоков", конечно.
Здравствуйте, vdimas, Вы писали: V>Странно рассуждаешь. )) V>В Spin-wait не происходит ничего, кроме удержания ресурсов процессора, а тут в очередь достоверно ставятся элементы, пока крутится цикл, просто они ставятся в других потоках. Т.е., блокировки очереди нет, именно поэтому lock-free.
Классический spin-wait — активное ожидание ресурса: в цикле проверяешь, когда же тебе наконец-то что-то станет доступно.
while ((local_i = atomic_load(&i)) == 0) {
/* do nothing - just keep checking over and over */
}
Посмотри внимательнее:
do {
node.Next = head.Next;
} while (!CAS(ref head.Next, node.Next, node));
Здесь CAS — это просто оптимизация того, насколько времени блокируется голова стека. Сама блокировка потока исполнения и блокировка элемента никуда не исчезает, просто хорошо оптимизирована за счёт реализации "в железе". Искренее считаю что это реализуемо и без аппаратного CAS (допустим префикс lock не работает и нет способа выставить сигнал lock на шину) — сами значения в памяти могут быть соответствующим "сигналом". Алгоритм Деккера и Решение Петтерсона вроде бы именно про это.
V>И если конкурирующий поток уйдёт в спячку через вытеснение, то очередь не останется надолго заблокированной, как оно было бы при защите обычной очереди мьютексом, если бы перед вытеснением поток завладел бы ресурсом.
Ты как будто про мьютекс пишешь: это его можно захватить, это он может принадлежать какому-то потоку после чего-нибудь типа WaitForSingleObject(). Многие вот так и попадают в эту ловушку мышления, рассуждая в парадигме "захватить ресурс". Однако задача-то в другом: выполнить участок кода атомарно, какое-то действие сделать атомарно. Если ты отбрасываешь парадигму "ресурс принадлежит потоку", стремясь только к тому чтобы выполнять отдельные действия атомарно (что есть изначальная цель), то такие алгоритмы получаются сами собой.
V>Зачастую это плохая практика. V>При нужной расстановке приоритетов потоков выгодней уходить в спячку, чем крутить 10 GOTO 10.
Вот нифига подобного, не согласен: почти во всех гайдлайнах, и Best practсies говорится о том, что блокировка должна выставляться на минимально возможное время. Это то самое время, чтобы что-то атомарно сделать — чтоб данные консистентными оставались. Если строго следовать этим рекомендациям, то большая часть блокировок будет на время порядка десятка тактов процессора — именно столько действительно требуется чтобы обновить несколько участков памяти. V>Например, в твоём цикле указан код писателя. V>А что делать читателю в отсутствии данных?
В моём коде читателю при отсутствии данных не надо делать ничего: там речь про OnScreenDisplay — пока я не закончу формирование данных, показывать нечего — или предыдущее значение, или ничего. Мусор показывать бессмысленно.
Читатель, увидев m_rtssMemory->dwBusy, может идти дальше ничего не обновляя на экране — данные ещё не готовы. V>Если же ядра унутре однопоточные, то PAUSE не делает аж ничего, это аналог NOP.
ВСЕ(!) ядра у современных интеловских процессоров МНОГОпоточные. Это проистекает из того, что все современные интеловские (и АМД'шные) процессоры суперскалярные — они имеют несколько конвейров (pipelines), и исполняют инструкции параллельно.
А кроме того, современные процессоры имеют блок предсказания ветвлений и спекулятивное исполнение — параллельно выполняют инструкции, которые теоретически могут оказаться следующими в потоке.
Тащемта это официальная рекомендация от Intel:
1
13.5.3 Spin-Wait Loops
Use the PAUSE instruction in all spin wait loops. The PAUSE instruction de-pipelines the spin-wait loop to
prevent it from consuming execution resources excessively and consuming power needlessly.
When executing a spin-wait loop, the processor can suffer a severe performance penalty when exiting
the loop because it detects a possible memory order violation and flushes the core processor's pipeline.
The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. The
processor uses this hint to avoid the memory order violation and prevent the pipeline flush. However, you
should try to keep spin-wait loops with PAUSE short.
2
3.4.1 Branch Prediction Optimization
Branch optimizations have a significant impact on performance. By understanding the flow of branches
and improving their predictability, you can increase the speed of code significantly.
Optimizations that help branch prediction are:
• Keep code and data on separate pages. This is very important; see Section 3.6, “Optimizing Memory
Accesses,” for more information.
• Eliminate branches whenever possible.
• Arrange code to be consistent with the static branch prediction algorithm.
• Use the PAUSE instruction in spin-wait loops.
• Inline functions and pair up calls and returns.
• Unroll as necessary so that repeatedly-executed loops have sixteen or fewer iterations (unless this
causes an excessive code size increase).
• Separate branches so that they occur no more frequently than every three micro-ops where possible.
3
8.4.2 Synchronization for Short Periods
The frequency and duration that a thread needs to synchronize with other threads depends application
characteristics. When a synchronization loop needs very fast response, applications may use a spin-wait
loop.
A spin-wait loop is typically used when one thread needs to wait a short amount of time for another
thread to reach a point of synchronization. A spin-wait loop consists of a loop that compares a synchronization variable with some pre-defined value. See Example 8-4(a). On a modern microprocessor with a superscalar speculative execution engine, a loop like this results in
the issue of multiple simultaneous read requests from the spinning thread. These requests usually
execute out-of-order with each read request being allocated a buffer resource. On detection of a write by
a worker thread to a load that is in progress, the processor must guarantee no violations of memory
order occur. The necessity of maintaining the order of outstanding memory operations inevitably costs
the processor a severe penalty that impacts all threads. This penalty occurs on the Pentium M processor, the Intel Core Solo and Intel Core Duo processors.
However, the penalty on these processors is small compared with penalties suffered on the Pentium 4
and Intel Xeon processors. There the performance penalty for exiting the loop is about 25 times more
severe.
On a processor supporting HT Technology, spin-wait loops can consume a significant portion of the
execution bandwidth of the processor. One logical processor executing a spin-wait loop can severely
impact the performance of the other logical processor.
Это из Intel® 64 and IA-32 Architectures Optimization Reference Manual. Советую туда заглянуть — там много любопытного написано.
Да, я тут "многопоточность ядер" понимаю не как в Pentium-4, не про Hyper-Threading, не про SMT. Тем не менее исполнительных блоков у современных ядер процессоров более одного — в этом плане они "многопоточные".
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
V>>В Spin-wait не происходит ничего, кроме удержания ресурсов процессора, а тут в очередь достоверно ставятся элементы, пока крутится цикл, просто они ставятся в других потоках. Т.е., блокировки очереди нет, именно поэтому lock-free.
Ф>Классический spin-wait — активное ожидание ресурса: в цикле проверяешь, когда же тебе наконец-то что-то станет доступно. Ф>
Ф>while ((local_i = atomic_load(&i)) == 0) {
Ф> /* do nothing - just keep checking over and over */
Ф> }
Ф>
Здесь простое ожидание.
Конкурирующий поток, захвативший ресурс, может быть вытеснен, и еще "долго" не получит тиков процессора, в этом и заключается потенциальная неэффективность блокирующих схем.
Ф>Посмотри внимательнее: Ф>
Ф> do {
Ф> node.Next = head.Next;
Ф> } while (!CAS(ref head.Next, node.Next, node));
Ф>
А здесь попытка конкурентной модификации, разница принципиальная — если конкурирующий поток будет вытеснен, то цикл сразу же исполнится.
На деле же, с большой вероятностью он исполнится за единицы итераций (т.е. за несколько десятков наносекунд) даже если конкурирующий поток не будет вытеснен.
А с ~99% вероятностью (для случая двух случайно пишущих в очередь потоков) этот цикл исполняется с первого раза.
Не веришь — напиши простой тест, да погоняй.
Надо примерно так:
var top = _top;
node._next = top;
while(!CAS(ref _top, /* new */ node, /* old */ top)) {
top = _top;
node._next = top;
}
PAUSE тут не нужен, т.к., наоборот, после конфликта надо как можно скорее сделать новую попытку.
Я когда-то много гонял именно этот сценарий, собирал статистику происходящего (по кол-ву оборотов цикла).
Она весьма радует. ))
Ф>Здесь CAS — это просто оптимизация того, насколько времени блокируется голова стека.
Это состязательный аппаратный процесс длительностью около 15 тактов процессора.
Ф>Сама блокировка потока исполнения и блокировка элемента никуда не исчезает, просто хорошо оптимизирована за счёт реализации "в железе".
Ну, блин, стоимость операции в 15 тактов или в ~150 миллионов тактов в случае вытеснения конкурирующего потока, захватившего через мьютекс ресурс...
Ф>Искренее считаю что это реализуемо и без аппаратного CAS (допустим префикс lock не работает и нет способа выставить сигнал lock на шину) — сами значения в памяти могут быть соответствующим "сигналом". Алгоритм Деккера и Решение Петтерсона вроде бы именно про это.
Не-а, оно резко дороже.
Я тоже в студенчестве разрабатывал похожие алгоритмы на трёх флагах, оно примерно это же получилось. ))
Там одна-две записи и одно-два чтения (как повезёт).
Причём, запись и чтение происходят на расшаренной линейке кеша, где стоимость аппаратной синхронизации при одновременной записи и чтения в эту линейку кеша двумя ядрами составляет примерно десяток тактов на телодвижения по обеспечению когерентности на каждую операцию. Это почему данные разных потоков зачастую разносят на величину, заведомо большей величины линейки кеша.
Плюс, эти алгоритмы реализуют мьютекс, т.е. в случае вытеснения конкурирующего потока, захватившего ресурс, второй поток будет его "долго" ждать.
Плюс, эти алгоритмы работают только для двух одновременных потоков — для большего числа потоков необходимо добавлять флаги по одному на поток.
А показанный мною код обслуживает сколько угодно много потоков на запись и чтение.
Впрочем, кто тебе мешает самостоятельно провести тесты и сравнить?
V>>И если конкурирующий поток уйдёт в спячку через вытеснение, то очередь не останется надолго заблокированной, как оно было бы при защите обычной очереди мьютексом, если бы перед вытеснением поток завладел бы ресурсом. Ф>Ты как будто про мьютекс пишешь: это его можно захватить, это он может принадлежать какому-то потоку после чего-нибудь типа WaitForSingleObject(). Многие вот так и попадают в эту ловушку мышления, рассуждая в парадигме "захватить ресурс". Однако задача-то в другом: выполнить участок кода атомарно, какое-то действие сделать атомарно. Если ты отбрасываешь парадигму "ресурс принадлежит потоку", стремясь только к тому чтобы выполнять отдельные действия атомарно (что есть изначальная цель), то такие алгоритмы получаются сами собой.
Если что-то надо выполнить "атомарно", например, записать последнюю отметку времени, где эта отметка представлена значением шириной в слово, то это можно сделать безо-всяких специальных алгоритмов вовсе. Просто пиши из разных потоков в эту ячейку и всё. ))
Но на практике мы совершаем неатомарные операции.
Например, в показанном мною коде есть две операции — инициализация node._next текущим значением _top и попытка записать этот новый _top=node.
В алгоритме Деккера необходимо будет захватить сначала некий "софтовый" этот мьютекс, потом выполнить эти две операции (уже без цикла), затем отпустить этот мьютекс.
Хрень получается. ))
И дорого в тактах (ведь CAS одновременно сравнивает и записывает в память в случае удачи, т.е. смотреть надо не на стоимость CAS, а на то, насколько он дороже обычной конкурирующей записи в линейку кеша — дороже на пяток тактов всего), и потенциальное столкновение потоков...
V>>Зачастую это плохая практика. V>>При нужной расстановке приоритетов потоков выгодней уходить в спячку, чем крутить 10 GOTO 10. Ф>Вот нифига подобного, не согласен: почти во всех гайдлайнах, и Best practсies говорится о том, что блокировка должна выставляться на минимально возможное время.
Это по результатам тестов систем, которые можно назвать СМО (системы массового обслуживания).
Spin-wait делает всю систему резко неэффективной. ))
Не зря же в серверной конфигурации Windows у мьютексов поле spin count обычно инициализируется нулём.
На деле, его надо инициализировать нулём и для ОЧЕНЬ многих сценариев клиентского кода.
И вообще, "родной" мьютекс использовать моветон, он очень дорогостоящий, там слишком много ветвлений, например, по значению поля SpinCount структуры.
Самописные мьютексы дешевле в разы.
V>>Например, в твоём цикле указан код писателя. V>>А что делать читателю в отсутствии данных? Ф>В моём коде читателю при отсутствии данных не надо делать ничего: там речь про OnScreenDisplay — пока я не закончу формирование данных, показывать нечего — или предыдущее значение, или ничего. Мусор показывать бессмысленно.
Ну вот я и спрашиваю — нафига ожидать готовность данных по spin wait? ))
Не лучше ли насильно уйти в спячку в ожидание сигнала, т.е. отдать процессор другим задачам?
Ф>Читатель, увидев m_rtssMemory->dwBusy, может идти дальше ничего не обновляя на экране — данные ещё не готовы.
Куда "идти"-то? ))
V>>Если же ядра унутре однопоточные, то PAUSE не делает аж ничего, это аналог NOP. Ф>ВСЕ(!) ядра у современных интеловских процессоров МНОГОпоточные.
Не у "современных", а у "новых".
Актуальное десктопное и ноутбучное железо сегодня работает по 10 лет с лишним. ))
И у ARM этого тоже пока нет.
Да и, PAUSE хороша в мат.вычислениях, когда надо освободить умножители/делители (в т.ч. с плавающей точкой) для конкурирующего гиперпотока, а в показанном цикле CAS эта инструкция лишь повышает вероятность повторного столкновения потоков, бо в том цикл нечего освобождать — там лишь пересылки и простые сравнения, которые исполняются в современных процах без специального аккумулятора-сумматора, т.е. прямо в регистрах через схемы сравнения.
Ф>А кроме того, современные процессоры имеют блок предсказания ветвлений и спекулятивное исполнение — параллельно выполняют инструкции, которые теоретически могут оказаться следующими в потоке.
На это PAUSE не влияет, бо эти блоки "личные" у каждого гиперпотока.
Собсно, эти блоки и образуют "гиперпоток". ))
Ф>Тащемта это официальная рекомендация от Intel: Ф>
13.5.3 Spin-Wait Loops
Ф>Use the PAUSE instruction in all spin wait loops.
CAS — это не spin-wait ни в одном из мест.
Твоё заблуждение уже малость неприлично.
Это похоже на spin-wait, но разница принципиальная.
Spin-wait на практике крутят десятки-сотни микросекунд, это в 1-10 тыс раз дольше твоего цикла CAS.
Это несравнимые порядки величин, поэтому рекомендации по spin-wait неприменимы к lock-free алгоритмам. ))
И да, похоже, что ты сам не читаешь, что цитируешь:
On a processor supporting HT Technology, spin-wait loops can consume a significant portion of the execution bandwidth of the processor. One logical processor executing a spin-wait loop can severely impact the performance of the other logical processor.
Это возвращаясь к твоей реакции:
V>>При нужной расстановке приоритетов потоков выгодней уходить в спячку, чем крутить 10 GOTO 10.
Ф>Вот нифига подобного, не согласен
У тебя теоретизирование, а у меня тщательные исследования на разном железе в своё время...
Здравствуйте, Философ, Вы писали:
Ф>Без блокировок совсем не выходит
В большинстве случаев выходит, но может потребоваться заметное усложнение алгоритма.
Ф>название "lock-free" — это обман.
Судя по всему, Вы не поняли принципиальной разницы между блокирующими и неблокирующими алгоритмами.
В блокирующих алгоритмах с разделяемым ресурсом работает только один поток, получивший к нему временный доступ (тот самый mutex). Остальные потоки, которым в это время требуется ресурс, не имеют другого выхода, как ждать его освобождения. Когда поток, захвативший ресурс, выполняется достаточно быстро, этот алгоритм работает хорошо. Но, если этот поток вдруг будет прерван на значительное время, эффективность алгоритма падает обвально.
В неблокирующих алгоритмах с разделяемым ресурсом может работать любой из конкурирующих потоков, и они все равноправны. Алгоритм строится так, что каждый поток на очередном шаге, с помощью атомарных команд, совершает какое-то действие, которое либо продвигает процесс обработки общего ресурса, либо не делает ничего, если этот процесс уже успел продвинуть один из других потоков. По сути, они в случайном порядке "тыкаются" в ресурс, пытаясь общими усилиями привести его в нужное состояние (например, вставить элемент в список). В среднем это может получиться более затратным, чем с блокирующими алгоритмами, зато верхний предел затрат вполне детерминирован, поскольку для выполнения операции требуется ограниченное число шагов. Если хоть один конкурирующих потоков будет выполняться — он гарантированно завершит операцию с общим ресурсом.
Есть также разновидность синхронизации, которую называют "lock-free" просто потому, что в ней ни один поток явно не ждет освобождения ресурса, а пытается получить к нему доступ при помощи атомарных команд типа test-and-set, и затем тот поток, которому удалось получить доступ, работает с ресурсом до его освобождения. Остальные потоки в это время, видя, что ресурс захвачен, просто занимаются другими делами. С точки зрения потоков, это действительно lock-free (ни один поток не блокируется в ожидании). Но с точки зрения ресурса, это по-прежнему блокирующий алгоритм, поскольку ресурс фактически зарезервирован за единственным потоком и, если тот будет прерван, то обработка ресурса затянется на неопределенное время.
Ф>Без блокировок совсем не выходит: другое ядро или другой процессор никаким другим способом не может синхронизировать работу с участком памяти, только блокировки, только сигнал LOCK.
Аппаратная блокировка шины — полностью детерминированная операция, она всегда гарантированно завершается за определенное количество тактов.
Здравствуйте, Sharov, Вы писали:
S>Собственно, из-за этого в процессах появлись потоки. На уровне потоков все шустрее.
Там разница лишь в том, что процесс выделен в качестве контейнера для потоков. Классическая модель UNIX просто совмещает процесс, как контейнер, с единственным потоком в нем. В отношении планирования/диспетчеризации никакой разницы нет.
S>как оно на уровне процессов, а не потоков я не в курсе.
Если мы про винду, то в ней в планировании участвуют исключительно потоки. Процесс представляет собой лишь "расширенный контекст" (адресное пространство, ресурсы, общие свойства и т.п.).
S>Возможно дейстивительно поэтому в ядре lock-free и не взлетает, т.к. на уровне процессов это крайне сложно, если вообще возможно.
В смысле? Что именно "не взлетает" и "крайне сложно"?
Здравствуйте, vdimas, Вы писали:
V>В кооперативной-однопроцессорной (одноядерной) многозадачности оно таким злом не было за невозможностью. V>Вот там мьютексы были паиньками, что ими всё засрали нахрен в 80-е до 95-го, а потом как ужаснулись, когда пошло более одного ядра + вытесняющая многозадачность...
Не сгущайте красок. При любой многозадачности мьютексы прекрасно работают до определенного уровня загрузки, и лишь после нее начинается лавинообразный рост коллизий. Это ж, по сути, классическая система массового обслуживания — турникет, дорога, транспорт, телефонная сеть и прочее, она требует прежде всего оптимизации по ресурсам. Менять алгоритмы требуется лишь при специфических требованиях, вроде hard realtime. Soft realtime с любым разумным средним временем отклика достигается масштабированием.
V>переключение потока дорогое еще для потока, который вытесняют V>Который поток ставят — его дорого ставить
Все эти оценки "дорого-дешево" имеют смысл только в отношении удельного веса в общей совокупности затрат. Если все остальное уже оптимизировано, и на первое место вылезли затраты на переключение — значит, их действительно пора оптимизировать. Но, если мы сейчас прикинем вес затрат на переключение на фоне веса затрат, создаваемых типичным современным софтом, нам потребуется неслабый микроскоп, чтоб их разглядеть.
Так что об этих затратах уместно говорить в контексте какой-нибудь специализированной промышленной системы, софт под которую или писан с нуля квалифицированными кадрами, или ими же переделан из софта общего назначения. Если же взять навскидку произвольную систему общего назначения, от которой ожидается realtime в плане той же мультимедии, то затраты на переходы в режим ядра, переключение контекста и подобное — одни из последних кандидатов на оптимизацию.
V>Т.е., lock-free гарантирует, что в каждый момент времени хотя бы один поток продвигается в своём исполнении.
Да, но только если это lock-free одновременно и для потоков, и для их общих ресурсов.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Не сгущайте красок. При любой многозадачности мьютексы прекрасно работают до определенного уровня загрузки, и лишь после нее начинается лавинообразный рост коллизий.
В кооперативной однопроцессорной (одноядреной) многозадачности ожидающий на мьютексе поток освободит ресурс, что позволит с большой вероятностью отдать (рано или поздно) процессор обратно потоку, который захватил мьютекс. А при правильном написании кода, т.е. если не будет ожидающих сигналов/хендлов операций в промежутках между захватом и отпусканием, то поток, захвативший мьютекс, никогда не будет неожиданно вытеснен. С коллизиями столкнулись именно при насильном вытеснении потоков и именно в защищённом режиме, бо в плоском режиме переключение потоков было достаточно дешевым.
ЕМ>Это ж, по сути, классическая система массового обслуживания
Которые, по-классике, пишутся не на мьютексах, а на семафорах и атомарных (lock-free в мультипроцессорной конфигурации) операциях.
Мьютексы — это дешевый механизм обеспечения сериализации доступа к ресурсу для случая, когда "облом подумать". ))
V>>переключение потока дорогое еще для потока, который вытесняют V>>Который поток ставят — его дорого ставить ЕМ>Все эти оценки "дорого-дешево" имеют смысл только в отношении удельного веса в общей совокупности затрат.
Разумеется.
Стоимости промаха TLB в инете есть — можно оценивать.
Но лучше всего гонять конкретные сценарии в тестах в различных техниках исполнения, конечно.
ЕМ>Если все остальное уже оптимизировано, и на первое место вылезли затраты на переключение — значит, их действительно пора оптимизировать.
Угу. Например, мы обслуживаем скоростную диспетчеризацию из сотен/тысяч источников.
Тут переключения контекстов могут отожрать до 95% всех тиков, если каждый источник обрабатывается отдельным потоком ОС.
ЕМ>Но, если мы сейчас прикинем вес затрат на переключение на фоне веса затрат, создаваемых типичным современным софтом, нам потребуется неслабый микроскоп, чтоб их разглядеть.
Если мы говорим об эффективности и реалтайме, то обычно и платформы используются соответствующие.
С/С++ или тот же дотнет в специальном "оптимизированном" режиме написания кода, чтобы не дёргать GC на каждый чих и вообще с уменьшенной суммарной косвенностью графа объектов.
ЕМ>Так что об этих затратах уместно говорить в контексте какой-нибудь специализированной промышленной системы, софт под которую или писан с нуля квалифицированными кадрами
Никак не отвыкну от привычки думать, что софт, требующий хоть какую-то эффективность, и должен писаться "квалифицированными кадрами". ))
Т.е. с целевым образованием и хотя бы 3-5тилетним опытом именно в области эффективного программирования.
ЕМ>Если же взять навскидку произвольную систему общего назначения, от которой ожидается realtime в плане той же мультимедии, то затраты на переходы в режим ядра, переключение контекста и подобное — одни из последних кандидатов на оптимизацию.
Ну-ну-ну... ))
Этот "софт общего назначения", для случая мультимедиа, построит граф узлов в каком-нить DirectShow или прочих OpenAL и скажет этому графу "старт!"
А далее будет работать охрененно вылизанные подкапотные вещи использованной либы — кодеки/фильтры, источники и приёмники сигналов и т.д.
Т.е., задача прикладного кода сводится лишь к построениях графа из готовых кубиков и конфигурированию его.
Но мы-то обсуждаем "кишки". ))
V>>Т.е., lock-free гарантирует, что в каждый момент времени хотя бы один поток продвигается в своём исполнении. ЕМ>Да, но только если это lock-free одновременно и для потоков, и для их общих ресурсов.
Здравствуйте, Евгений Музыченко, Вы писали:
S>>Собственно, из-за этого в процессах появлись потоки. На уровне потоков все шустрее. ЕМ>Там разница лишь в том, что процесс выделен в качестве контейнера для потоков. Классическая модель UNIX просто совмещает процесс, как контейнер, с единственным потоком в нем. В отношении планирования/диспетчеризации никакой разницы нет.
При переключение потоков контекст процесса не переключается, в отличие переключения процессов.
Если об этом речь.
S>>как оно на уровне процессов, а не потоков я не в курсе. ЕМ>Если мы про винду, то в ней в планировании участвуют исключительно потоки. Процесс представляет собой лишь "расширенный контекст" (адресное пространство, ресурсы, общие свойства и т.п.).
Ну когда-то же происходит переключение процессов, на поток из другого процесса? Вот тогда это долго.
S>>Возможно дейстивительно поэтому в ядре lock-free и не взлетает, т.к. на уровне процессов это крайне сложно, если вообще возможно. ЕМ>В смысле? Что именно "не взлетает" и "крайне сложно"?
lock-free алгоритмы в ядре. Легко сделать сильно неочевидный баг. В ядрах все должно быть максимально просто.
Здравствуйте, vdimas, Вы писали:
V>Тут переключения контекстов могут отожрать до 95% всех тиков, если каждый источник обрабатывается отдельным потоком ОС.
Какой смысл для каждого источника создавать поток? Выделенный поток имеет смысл, если он работает с источником бОльшую часть времени. Если же он преимущественно спит, то такое раздувание количества потоков и является основной причиной затыков.
V>Никак не отвыкну от привычки думать, что софт, требующий хоть какую-то эффективность, и должен писаться "квалифицированными кадрами". ))
Мне тоже сложно думать иначе, но подход "возьмите молоток побольше" уже давно преобладает везде, кроме совсем уж критичных участков. И даже там изо всех сил пытаются упрощать и послаблять.
V>А далее будет работать охрененно вылизанные подкапотные вещи использованной либы — кодеки/фильтры, источники и приёмники сигналов и т.д.
И кто ж их охрененно-то вылижет? Да, кто-то и посейчас тщательно следит за использованием ресурсов, но большинство ж, сидя на топовом железе, вообще ни разу не тестирует свои поделия на более слабом. "У меня работает — значит, и у других будет".
Кстати, тот же DirectShow можно считать достаточно оптимальным лишь для типовой потоковой обработки, не требующей особой динамики. При попытке собрать таким образом какой-нибудь блок эффектов для гитары сразу станет грустно. Именно поэтому и родили в свое время предельно упрощенный и аскетичный ASIO.
Здравствуйте, Sharov, Вы писали:
S>При переключение потоков контекст процесса не переключается, в отличие переключения процессов.
Переключение контекста процесса как раз значительно проще — для этого всего-то нужно перезагрузить несколько регистров (в том числе MMU). Там потери в основном на перезагрузки кэшей, но это происходит и при работе потоков без переключения. Во многих случаях переключение между двумя потоками одного процесса может перетряхивать кэши сильнее, чем между двумя потоками из разных процессов.
S>lock-free алгоритмы в ядре. Легко сделать сильно неочевидный баг. В ядрах все должно быть максимально просто.
Когда реально нужны оптимизация/функциональность, в ядро тащат все, что требуется.
Здравствуйте, Евгений Музыченко, Вы писали:
S>>При переключение потоков контекст процесса не переключается, в отличие переключения процессов. ЕМ>Переключение контекста процесса как раз значительно проще — для этого всего-то нужно перезагрузить несколько регистров (в том числе MMU). Там потери в основном на перезагрузки кэшей, но это происходит и при работе потоков без переключения. Во многих случаях переключение между двумя потоками одного процесса может перетряхивать кэши сильнее, чем между двумя потоками из разных процессов.
Это уж как напишете. При переключении процессов это всегда происходит, а потоков зависит от реализации.
Здравствуйте, Евгений Музыченко, Вы писали:
V>>Тут переключения контекстов могут отожрать до 95% всех тиков, если каждый источник обрабатывается отдельным потоком ОС. ЕМ>Какой смысл для каждого источника создавать поток? Выделенный поток имеет смысл, если он работает с источником бОльшую часть времени. Если же он преимущественно спит, то такое раздувание количества потоков и является основной причиной затыков.
Вопрос был про стоимость переключений контекстов — я привёл известный сценарий, показывающий эту стоимость.
V>>Никак не отвыкну от привычки думать, что софт, требующий хоть какую-то эффективность, и должен писаться "квалифицированными кадрами". )) ЕМ>Мне тоже сложно думать иначе, но подход "возьмите молоток побольше" уже давно преобладает везде, кроме совсем уж критичных участков. И даже там изо всех сил пытаются упрощать и послаблять.
ОК.
Но в теме о реалтайме это оффтоп, ИМХО.
V>>А далее будет работать охрененно вылизанные подкапотные вещи использованной либы — кодеки/фильтры, источники и приёмники сигналов и т.д. ЕМ>И кто ж их охрененно-то вылижет?
Разработчики в этой области, вестимо.
Область-то специфическая. ))
ЕМ>Да, кто-то и посейчас тщательно следит за использованием ресурсов, но большинство ж, сидя на топовом железе, вообще ни разу не тестирует свои поделия на более слабом. "У меня работает — значит, и у других будет".
Да ну не...
DirectShow, DirectSound или всякие speex вылизаны очень даже неплохо.
Оно ж всё вылизывалось еще для техники 90-х как по общей архитектуре (путям прохождения/обработки данных), так и по публичному АПИ, суть которого сводится к конфигурированию/настройке общего графа устройств + обработчиков.
ЕМ>Кстати, тот же DirectShow можно считать достаточно оптимальным лишь для типовой потоковой обработки, не требующей особой динамики. При попытке собрать таким образом какой-нибудь блок эффектов для гитары сразу станет грустно.
Ес-но, из блоков DirectShow блок эффектов не собирают. ))
Подход был отродясь другой — весь блок эффектов представляет из себя один узел фильтра DirectShow.
Задача этого фильтра — обработать порцию данных по входу, положив результат по выходу.
Примитивнейшее и эффективное АПИ.
И уж прояви себя через эффективный матан между входом и выходом! ))
ЕМ>Именно поэтому и родили в свое время предельно упрощенный и аскетичный ASIO.
Э, нет! ))
ASIO — это дыра не через софтовый драйвер, а через нагромождения в железе.
Ведь основные фильтры/микшеры/массивы_микрофонов и прочие приблуды живут в DSP звуковых микросхем, поэтому ASIO был придуман, чтобы обойти именно этот аппаратно-программный конвейер, получив данные прямо от, считай АЦП (или из пакетов USB 3.0) и отправив их обратно в буфер ЦАП (или прямо в буфер пакетов USB 3.0), минуя всяческую обработку ср-вами ОС и драйвера, как оно есть для ЛЮБЫХ подключенных звуковых устройств.
Не зря ASIO — это опциональная фича драйвера конкретной звуковой микросхемы или платы (в т.ч. внешней).
И не зря эта фича достаточно редка в "обычном" железе.
Устройства ввода и вывода в полноценном ASIO захватываются в исключительном режиме и не доступны аудио-системе Windows, т.е. ползунок громкости и прочие вещи на них не влияют.
Это как бы параллельная вселенная, не связанная с подсистемой аудио виндов, оно может крутиться независимо друг от друга, что я и делал — проигрывал музыку заднего фона обычными проигрывателями Windows, а гитару подключал через внешнюю USB-картейку по входу и выходу, и далее на выходе простой микшер, куда подключен обычный звуковой выход компа и звуковой выход внешней картейки, а с микшера уже на усилок.
Здравствуйте, vdimas, Вы писали:
V>Но в теме о реалтайме это оффтоп, ИМХО.
Если бы. Всегда ж у нанимателя есть выбор — искать квалифицированного и опытного разработчика, или взять первого мало-мальски подходящего.
ЕМ>>И кто ж их охрененно-то вылижет?
V>Разработчики в этой области, вестимо. V>Область-то специфическая. ))
Я Вас умоляю. Работаю в этой области уже три десятка лет, реально вылизанный софт встречается очень редко. Даже у самих MS в звуковой подсистеме полно косяков и откровенных багов, которые не правятся десятилетиями, поскольку мало кого сильно напрягают — в большинстве случаев можно как-то выкрутиться.
V>DirectShow, DirectSound или всякие speex вылизаны очень даже неплохо. V>Оно ж всё вылизывалось еще для техники 90-х
Сам движок DirectShow действительно не слишком поменялся, но его никогда не позиционировали именно на реактивность. Его главное назначение — собрать граф, который будет гнать непрерывный стабильный поток, не предполагающий более быстрых изменений, чем ручные регулировки. Типовая задержка от входа до выхода там обычно в сотни миллисекунд, тщательной настройкой можно стабилизировать на нескольких десятках, но сгородить на нем ту же обработку голоса, при которой не слышно задержки, на стандартных фильтрах не получится.
Ну а DirectSound в Vista и вовсе превратился в тыкву, и теперь работает даже не через более-менее приличный WASAPI, а через самый древний и тормозной MME, поэтому даже для эффектов в играх годится едва-едва.
V>Ес-но, из блоков DirectShow блок эффектов не собирают. ))
Я про законченную конструкцию, в виде ящика с динамиком, в который втыкается гитара.
V>весь блок эффектов представляет из себя один узел фильтра DirectShow. V>Задача этого фильтра — обработать порцию данных по входу, положив результат по выходу.
Вот типичный фильтр DirectShow использует буферизацию в десятки-сотни миллисекунд, и это чаще всего не управляется.
V>ASIO — это дыра не через софтовый драйвер, а через нагромождения в железе.
ASIO — это прежде всего API, примитивный и убогий. Через что он будет работать, определяется исключительно реализацией. Но даже самые лучшие реализации ASIO работают через софтовые драйверы, ибо напрямую к железу их никто не пустит.
Есть реализации ASIO даже поверх MME, чтоб хоть как-то завести ASIO-only софт с адаптером, для которого нет драйвера ASIO. А есть реализации MME непосредственно через драйвер ядра, минуя промежуточные уровни звуковой подсистемы.
V>Ведь основные фильтры/микшеры/массивы_микрофонов и прочие приблуды живут в DSP звуковых микросхем, поэтому ASIO был придуман, чтобы обойти именно этот аппаратно-программный конвейер
Кому Вы это объясняете? ASIO появился, когда я уже довольно плотно работал со звуком на PC, поэтому я хорошо помню всю эту историю. Единственной целью его разработки была тупо альтернативная работа с железом в обход стандартной виндовой звуковой подсистемы, которая тогда была чуть менее убога, и ориентирована прежде всего на обычный потоковый звук без выкрутас. К тому времени уже был DirectSound, но он был почти полностью заточен под воспроизведение, ибо предназначался в первую очередь для игр и эффектов, а запись в нем была предельно примитивная — возможно, ее предусмотрели просто "на всякий случай", без явных перспектив.
К тому времени чуть не каждый производитель мало-мальски серьезных звуковых карт городил для них свой API, с которым работали "родные" программы и некоторые "дружественные", но этот зоопарк никого не устраивал. Так что единственное, чем отличался API от Steinberg — это простота, достаточно полная документация, и доступный SDK. По уровню сложности ASIO примерно на том же уровне, что и плагины для WinAMP или Foobar2000. Но это было единственное, что на тот момент имелось сколько-нибудь универсального, и индустрия быстро на него подсела (явно не без содействия Steinberg). Ну а потом что-то переделывать было уже поздно, да никто и не горел желанием.
V>получив данные прямо от, считай АЦП (или из пакетов USB 3.0) и отправив их обратно в буфер ЦАП (или прямо в буфер пакетов USB 3.0)
Все это уже почти тридцать лет нетрудно проделать стандартными средствами KS, только удобнее.
V>минуя всяческую обработку ср-вами ОС и драйвера
А вот хрен-то там. Типичный звуковой адаптер обрабатывает поток, состоящий из кадров, в которых отсчеты всех каналов идут подряд, ибо это естественное представление цифрового потокового многоканального звука. В потоках ASIO подряд идут отсчеты каждого из каналов. Поэтому ASIO эффективно работает только с адаптерами, которые сами работают с набором одноканальных потоков, а не с одним многоканальным. Когда драйвер ASIO работает с типичным адаптером, он сам перекладывает отсчеты туда-сюда в промежуточной памяти. Сейчас это, конечно, не занимает столько времени, сколько в 90-х, а тогда это было вполне ощутимым при малых размерах буферов.
V>как оно есть для ЛЮБЫХ подключенных звуковых устройств.
Что значит "для любых"?
V>Не зря ASIO — это опциональная фича драйвера конкретной звуковой микросхемы или платы (в т.ч. внешней).
В каком смысле "не зря"? Написали драйвер ASIO — фича появилась, не написали — ее нет. В этом нет никакой философии, не стоит воспринимать это все с таким восторгом.
V>И не зря эта фича достаточно редка в "обычном" железе.
В железе "этой фичи" вообще нет, и быть не может. Максимум, что может быть в железе — это та самая аппаратная обработка совокупности одноканальных потоков, чтоб избавить от этого драйвер.
V>Устройства ввода и вывода в полноценном ASIO захватываются в исключительном режиме и не доступны аудио-системе Windows
Устройства KS, внезапно, ведут себя точно так же, но при этом являются стандартными для Windows.
V>Это как бы параллельная вселенная, не связанная с подсистемой аудио виндов
Господи, что за пафос... Как же вам всем засрали мозги, подавая примитивное поделие под видом революции...
V>оно может крутиться независимо друг от друга, что я и делал — проигрывал музыку заднего фона обычными проигрывателями Windows, а гитару подключал через внешнюю USB-картейку по входу и выходу, и далее на выходе простой микшер, куда подключен обычный звуковой выход компа и звуковой выход внешней картейки, а с микшера уже на усилок.
То же самое, внезапно, Вы могли бы сделать с любыми стандартными устройствами Windows, только задержки были бы побольше — за счет той самой универсальности и "невылизанности".
Здравствуйте, Евгений Музыченко, Вы писали:
V>>Но в теме о реалтайме это оффтоп, ИМХО. ЕМ>Если бы. Всегда ж у нанимателя есть выбор — искать квалифицированного и опытного разработчика, или взять первого мало-мальски подходящего.
Если тебе всё это время хотелось поговорить о несовершенстве этого мира — то я заранее согласен.
Но моё мнение по этому поводу куда как более категоричное, мне им лучше не светить лишний раз. ))
А то набегут "истерички" плеваться в "снобов".
Здравствуйте, vdimas, Вы писали:
V>Ну, не зря же программа Время начинается на цифровых телеках/приставках примерно на пол-секунды, а то и секунду позже, чем на аналоговых... ))
V>Там приличная буферизация именно для таких целей.
Там видео поток не mjpeg, Для сжатия на стороне сервера нужно минимум пару секунд в буфере иметь, а лучше больше. а то не сожмёшь видео. Телевизор же поток мгновенно показывает.