"Размер буфера DMA" определяется в основном размером обычной оперативной памяти. Оно ж оттуда читает.

Георгий Курячий Не вижу связи. Идея в том, что с устройством мы обмениваемся, допустим, килобайтными страницами, а прочитать-то надо мегабайт.

А так, к достоинствам можно добавить скорость работы даже обычного memcpy. DMA штука аппаратная, ей не надо тратить такты на сравнение не досчитал ли счетчик до максимума, на увеличение адресов. Плюс теоретически во время копирования ядро может заниматься другими делами. Правда, именно для memcpy это вряд ли оправдано. (UPD: а, уже описали ниже. Но да, когда я тестировал, memcpy через DMA было быстрее. Там что-то около 4 тактов на посылку, а при ручном копировании 8 что ли)

А еще возможность писать в управляющие регистры периферии, не только в регистры данных. То есть на DMA можно навесить довольно сложную логику, полностью независимую от ядра. Из самого простого (что я тестировал) - "программный" ШИМ на всех ножках. Таймер управляет DMA, DMA управляет таймером и портом ввода-вывода. Получаем переключение ножек с заданной периодичностью и заданными значениями.

Потенциально DMA еще умеет писать из периферии в периферию. И для отдельных задач это тоже нужно, но простой пример я так сразу не придумаю.

Второй адрес забыли:

Георгий Курячий А зачем каждый раз разрешать DMA? И что делать, если у устройства нет адресации (например, звуковая карта проигрывает звук)?

По окончании может быть сгенерировано прерывание "DMA закончило", "DMA передало половину данных" и др. Но зачастую удобнее обойтись без прерывания, просто поллингом. Ну то есть вот мы хотим послать строку на терминал. Выбрали адрес строки, выбрали длину, послали. Все, никаких действий по окончании от нас не требуется. Вот что требуется - если вдруг захотели послать следующую строку, надо проверить, не занят ли передатчик. Возможно, даже в цикле дождаться освобождения. Да, на счет регистра настроек DMA. Можно, скажем, настроить автоинкремент адреса передатчика и приемника. Если мы пишем в какой-нибудь UART, нам ведь нужно чтобы из памяти каждый раз читалась новая ячейка. А вот адрес регистра данных меняться не будет. При чтении - наоборот. А при memcpy меняться должны оба адреса. Еще бывает циклический режим, когда DMA автоматически перезапускается после полного цикла обмена. Это нужно, например, для периодического обновления экрана.

Мне все еще кажется, что лучше демонстрировать хоть на чем-то (каракатица или там qemu), чем обходиться одними словами.

Георгий Курячий Мне тоже, но времени на это точно не хватит, особенно если инструмент будет другой, и его тоже надо объяснять.

В контекста вашего курса это все еще хуже Рарса (не потыкать самостоятельно), но лучше, чем ничего. А уж работу с периферией (в т.ч. таймерами), уровнями привилегий, DMA на Каракатице показать вполне можно. Впрочем, это тоже можно обсудить летом. Авось НИИЭТ таки допилят 1921вг1т. Хотя вроде в феврале еще обещались...

Можно куда-нибудь добавить, что выгодно кешировать стек. Максимально локальная штука, к тому же максимально часто обновляемая и на запись и на чтение.

С чего это? lb прекрасно работает и с байтами. Мы же не про память программ говорим, где инструкции всегда выровнены на 2 (два, а не четыре) байта. К тому же на байтах оверхед еще нагляднее...

Георгий Курячий Потому что 32-разрядное машинное слово занимает 4 байта.

  1. Memory access — доступ к памяти
  2. Write back — запись в регистровый блок (обновление регистров)

Запись в память на 4 шаге происходит или на 5?

Георгий Курячий На четвёртом, нельзя же сделать обновление регистрового блока до чтения из памяти.

А то вдруг между 4 и 5 возникнет прерывание, и инструкция начнет выполняться заново. То есть одна и та же ячейка запишется дважды. Для обычной памяти это не страшно, а вот для периферии... Да и чтение. Оно ведь тоже может иметь побочные эффекты. Либо сочтем это несущественными тонкостями и на лекции не будем упоминать вовсе.

Георгий Курячий Значит, либо кто-то должен обеспечить идемпотентность операций, либо отключать кеш.

LecturesCMC/ArchitectureAssembler2026/11_CacheBPT/COKPOWEHEU (последним исправлял пользователь FrBrGeorge 2026-04-25 14:22:02)