Re: Отличное видео про io подсистему компьютера.
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.10.25 14:11
Оценка: 17 (3) +2
Здравствуйте, Sharov, Вы писали:

S>Отличный канал и отличное видео про io подсистему компьютера и ее устройства.

S>Автор рассмотрел Memory-mapped IO vs Port-mapped IO, programmed I/O (Polling) vs Interrupt-Driven I/O
S>Почему memory mapped IO все-таки не самый лучший способ обустраивать взаимодействие с железом. Особенно
S>см. слайд на https://youtu.be/tadUeiNe5-g?si=Hv7x9iKaSgqM-2eA&t=1284

У автора каша в голове и ролик тупой в доску.

Во-первых, отличие memory-mapped I/O и port-mapped I/O не играет такого принципиального значения. От того, что на x86 отдаются IN и OUT, это всё равно идёт через CPU. А на другой архитектуре, как ARM, уже в процессоре может быть заложено, например, что доступ по адресам 0÷3FFF_FFFF пошёл в оперативку, 4000_0000÷7FFF_FFFF — в ПЗУ, а 8000_0000÷BFFF_FFFF в I/O, причём к каждому своя шина своей специфической конструкции. Вообще отдельные команды IN/OUT это только линия 8080->x86, а остальные ничего, живут без них, но получая сходные результаты.

MMIO по сравнению с PMIO вкуснее несколькими вещами, про которые автор ни слова не сказал:
1. Для устройств типа видеоадаптера, сетевухи... можно отобразить их собственную память, вместо того, чтобы через регистры гонять данные или выделять куски оперативки для них. Это особенно для современных видеокарт.
2. Память устройства можно отобразить, регулируя доступ к ней у разных процессов. Пример 1 — таймер HPET: во всех современных ОС через него читают текущее время, не переключаясь в режим ядра. Пример 2 — сетевуха, в которой VLANы (или что там ещё будет) распределены между виртуалками, каждая получает свой VLAN через свои странички и думает, что у неё полная сетевуха (или явно знает, что один VLAN, но не имеет проблемы синхронизации с соседями). Во всех случаях нужно выделение по границам страниц виртуальной памяти.
3. Наконец, просто не нужно лишних команд и, при общей шине, отдельного типа обращений по ней.

А принципиально то, что или процессор гоняется сам по каждому байтику (это называется обычно Programmed I/O, PIO), или отдаёт операции с памятью на DMA модуль, который сам это делает. (В PCI, DMA называется busmastering, и ведётся самим устройством через встроенный DMA контроллер, суть та же). Но: если мы говорим про современные (⩾2008) процессоры x86, что Intel, что AMD, то там доступ между памятью и шинами всяких PCI всё равно бегает через процессор, через северный мост, который сейчас встроен в процессор. (А если несколько "камней" и соответственно несколько доменов — то ещё и через шину между ними.) На это не тратится управляющий блок CPU, но сам CPU всё равно участвует в этом.

И вот если расцепить это обратно, сделав мост между памятью и I/O (функция "северного моста") отделённой, то и скорость для чистых I/O операций может стать реально неограниченной (при использовании DMA // busmastering, вестимо). Но, судя по тому, что продолжают держать этот мост в процессоре, пока что отделять его невыгодно.

Далее, interrupt-driven I/O — это вообще не имеет никакого отношения к вопросу скорости одной передачи, это вопрос адекватного написания кода. Если любой код, который может выполняться, должен каждую микросекунду поллить все устройства, то так работать больше чем на пару килобайт не будет. Прерывания нужны для того, чтобы переключиться на специализированный код максимально близко к тому, когда нужно, без изменения(!) всего остального кода. А будет обработчик прерывания перекачивать данные по байтику, или, отметив завершение операции (когда устройство уже всё прочитало или записало), задать новую (если есть) — это одинаково и не зависит от того, MMIO или PMIO: или устройство умеет свою память или DMA, или корячиться по байтику (ладно, по слову).

Такое впечатление, что автор не видит различия между interrupt-driven I/O и DMA (busmastering).

И вот тут как раз стоит вспомнить channel-based I/O: пусть оно и есть только в одной, насколько я знаю, архитектуре (SystemZ): есть отдельные канальные процессоры, или попросту каналы, которые выполняют канальные программы, отдавая команды устройствам, принимая и передавая данные. Хаб, в который включаются канальные процессоры вместе с командными процессорами (обычными CPU), может отрабатывать доступ к памяти от обоих видов наравне, не ходя через CPU.

CBIO имеет свои недостатки. Например, таймер через него будет жутко неэффективен, поэтому в SystemZ он прямо в процессоре явными командами (да-да). Операции типа "запустить и ждать результата", как ожидание входящего пакета в сетевуху, на него плохо ложатся. Зато его колоссальное преимущество — оно проходит с минимальными затратами через виртуализацию: там, где даже у лучшего эмулятора диска на IO пространстве или памяти ты на каждую операцию с регистрами получишь прерывание эмуляции в гипервизор (поэтому драйвера виртуальных устройств стараются делать операции через подготовку структуры в памяти и один вызов гипервизора), тут запуск операции делается что на железе, что в виртуалке одной командой типа start device.

S>Объяснил почему ранние компьютеры были несовместимы -- всё делалось через mmi, но у каждого по-своему и гвоздями

S>прибивалось к материнке.

Вообще разные компьютеры между собой не очень совместимы. У одного, например, сетевуха RTL8139, у другого Attansic L3, и оба на материнке. Вот и ищи для каждого свой драйвер.

MMIO или нет, на это не влияло. Разные устройства — разные методы доступа. А когда ты выжимаешь каждый бит — то вообще о совместимости не думают. PMIO тоже различалось. NE2000, 3C905 и DEC Tulip все были сетевухами, но ничего общего в управлении не имели.

Какая-то унификация есть только на CBIO и только для команды "прочитать без особенностей" (код 02), потому что она для загрузки. Остальное — добрая воля (иногда под дулом пистолета или факов от Линуса) производителей железа.

До этого, у массовых компьютеров до PDP-11 вообще не было MMIO. PDP-11 почти первый с таким, а это 1970 год. Типовым тогда было наличие команд типа "отправить байт на перфоленту", "принять код с клавиатуры" — именно так, с фиксацией роли устройства за командой. Гибкости в виде смены адреса не было.

S/360 (предок SystemZ) тут был чуть ли не первый с универсализацией через набор команд типа start device, test device, через канальные процессоры, это 1964-66.

PDP-11 с принципом "у нас всё через чтение-запись памяти, только протокол уточнить и базовый адрес для конкретного экземпляра устройства" стал тем, за кем пошли чуть менее чем все (опять же, кроме IBM). PMIO образца 8080 возник от того, что разнесли в этом процессоре для микроконтроллера операции с памятью из-за другого протокола.

S>В общем, крайне годное, кмк, базовое видео про основы. Поэтому и на этом форуме.


Жаль. Потому что такая чушь только сбивает с толку.

S>ЗЫ: Странно, что про DMA немного, но там, на yt, есть на эту тему неплохие комментарии.

S>https://www.youtube.com/watch?v=tadUeiNe5-g

Ну так потому что невежа-автор не отличает DMA от прерываний — потому и немного.
The God is real, unless declared integer.
Отредактировано 13.10.2025 14:56 netch80 . Предыдущая версия . Еще …
Отредактировано 13.10.2025 14:18 netch80 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.