Прямой доступ к памяти

Материал из Википедии — свободной энциклопедии
(перенаправлено с «DMA»)
Перейти к навигации Перейти к поиску

Прямой доступ к памяти (англ. direct memory access, DMA) — режим обмена данными между устройствами компьютера или же между устройством и основной памятью, в котором центральный процессор (ЦП) не участвует. Так как данные не пересылаются в ЦП и обратно, скорость передачи увеличивается.

Описание работы

[править | править код]

Если требуется заполнить ячейки памяти, расположенные по подряд идущим адресам, используется «пакетный» (англ. burst) режим работы шины:

  • размер данных записывается в регистр контроллера DMA;
  • первый цикл используется для передачи адреса первой ячейки;
  • последующие циклы используются для пересылки данных указанного размера.

Аналогичная оптимизация работы ЦП с памятью крайне затруднена.

В оригинальной архитектуре IBM PC (шина ISA) DMA был возможен лишь при наличии аппаратного контроллера DMA (микросхема Intel 8237).

Контроллер DMA может получать доступ к системной шине независимо от ЦП и имеет несколько регистров. Регистры контроллера DMA доступны ЦП для чтения и записи и используются для задания:

  • номера порта, который должен быть использован для передачи данных;
  • вида операции (чтение или запись);
  • единицы переноса (побайтно или пословно);
  • размера данных, которые следует перенести, в байтах.

Рассмотрим процесс чтения данных с устройства. ЦП записывает значения в регистры контроллера DMA, отправляет устройству (например, диску) команду на чтение данных. Устройство читает данные (например, с диска) и записывает в свою внутреннюю память (буфер). Контроллер DMA устанавливает на адресную шину адрес памяти ПК, отправляет устройству запрос на чтение данных из внутренней памяти (буфера) устройства. Устройство получает запрос и при этом даже не знает, пришёл ли запрос от ЦП или от контроллера DMA. Устройство пересылает очередное слово из своей внутренней памяти (буфера) в оперативную память ПК по адресу, находящемуся на адресной шине. Затем устройство посылает контроллеру DMA сигнал, сообщающий об окончании записи. Контроллер DMA увеличивает адрес памяти ПК и выставляет его на адресную шину, уменьшает значение своего счётчика байтов, снова отправляет запрос на чтение данных из внутренней памяти (буфера) устройства. Цикл повторяется, пока значение счётчика не станет равно нулю. После окончания цикла устройство инициирует прерывание процессора, сообщающее о завершении переноса данных.

Контроллер DMA, способный выполнять несколько операций параллельно, называется многоканальным.

Захват шины (bus mastering)

[править | править код]

В шинах MicroChannel, SBus, разработанной под их большим влиянием PCI и её концептуальных производных AGP и PCI-X, используется иная реализация DMA. Эти шины позволяют любому устройству заявить о возникновении потребности к захвату шины, таковая потребность удовлетворяется так называемым арбитром при первой возможности. Устройство, успешно осуществившее захват шины, самостоятельно выставляет на шину сигналы адреса и управления и исполняет в течение какого-то времени ту же ведущую роль на шине, что и ЦП. Доступ ЦП к шине при этом кратковременно блокируется.

В такой реализации DMA не существует контроллера DMA, а также номера входа контроллера DMA.

Некоторые старые устройства с интерфейсом PCI, а именно, реализации звуковых карт семейства Sound Blaster, использовали DMA-контроллер 8237 из оригинальной архитектуры IBM PC. Такое использование, безусловно, является устаревшим для PCI, но поддерживалось с целью обеспечения полной совместимости по ПО и драйверам со звуковыми картами Sound Blaster для шины ISA.

Данная поддержка называется «Distributed DMA» (D-DMA) и реализована аппаратно как в устройстве, так и в логике моста PCI-ISA, в которой на PCI-системах размещена и логика DMA-контроллера 8237 (оригинального для IBM PC). В реализации используется два запроса: первый запрос от устройства к мосту PCI-ISA, второй — от моста к оперативной памяти ПК.

Кроме упомянутых реализаций Sound Blaster, практически никакие устройства PCI не используют понятие «номер входа DMA-контроллера», как и 8237 вообще.

В операционных системах со страничной виртуальной памятью, таких, как Windows и семейство UNIX, непрерывный регион виртуальных адресов может быть реализован разрывно расположенными физическими страницами.

Исполнение DMA по такому региону представляет собой довольно сложную задачу. Также сложной задачей является исполнение DMA по отгружаемой памяти.

Решение этой задачи требует выявления физических страниц, реализующих регион, и их блокировку от отгрузки обращением к подсистеме виртуальной памяти. Далее становится возможным нахождение физических адресов страниц региона, которые в общем случае не являются непрерывными и формируют так называемый «список рассеяния/сборки» (англ. scatter-gather list, SGL).

Задача исполнения DMA по таковому списку может быть решена одним из следующих способов.

  • Выделение подряд идущей физической памяти в ядре операционной системы и промежуточное копирование всех данных туда/оттуда (так называемый «буфер отскока» — англ. bounce buffer).
Поддерживается всеми ведущими операционными системами. Для активации поддержки в ОС Windows требуется вызов IoGetDmaAdapter с параметром DEVICE_DESCRIPTION::ScatterGather, установленном в FALSE.
Недостатки:
- трата времени процессора на копирование;
- потребление крайне ограниченного ресурса непрерывной физической памяти;
- занятие места в ограниченной части памяти, к которой есть доступ у DMA (первый гигабайт на x86).
  • Разбиение операции на подоперации по границам элементов SGL, с прерыванием в конце каждой операции.
Использовалось в старых 8-битовых SCSI-контроллерах, поставляемых со сканерами типа HP ScanJet.
Недостатки:
- большое количество прерываний.
  • Поддержка SGL самим устройством, с требованием копирования SGL, преобразованного в формат, специфичный для устройства, в устройство через многочисленные обращения к регистрам устройства.
Недостатки:
- крайне высокая сложность устройства;
- невысокая производительность большого числа записей в регистры.
  • Поддержка SGL самим устройством, с требованием размещения SGL, преобразованного в формат, специфичный для устройства, в физически непрерывном регионе основной памяти.
Устройство читает SGL тем же механизмом DMA с захватом шины, что и собственно данные, тем самым реализуя функциональность некоего процессора, читающего и исполняющего свою собственную «программу», реализованную как список дескрипторов SGL. Данная архитектура называется «цепной DMA» (англ. chain DMA), реализована в практически всем стандартном оборудовании современного компьютера — Intel IDE (англ. integrated drive electronics) (в примитивном виде), USB UHCI, USB OHCI, 1394 OHCI, а также в большинстве PCI-адаптеров, Ethernet и SCSI (даже в устаревшем AIC78xx). Хороший пример реализации данной архитектуры в очень сложном и развитом виде дан в спецификации оборудования 1394 OHCI. По некоторым сведениям, данная архитектура под названием «канальные программы» использовалась ещё в IBM 360, известных в СССР как ЕС ЭВМ.
Недостатки:
- высокая сложность устройства, хотя и меньшее количество транзисторов, чем в предыдущем варианте. Например, контроллер USB UHCI (согласно спецификации на сайте Intel) требует около 5000 транзисторов.
  • Поддержка SGL в межшинном оборудовании, при которой представление физически разрывного буфера для стороны устройства выглядит физически непрерывным.
Таковое оборудование называется IOMMU (англ. input/output memory management unit). Реализовывалось как на компьютерах фирмы Sun Microsystems для шины SBus, так и на компьютерах DEC Alpha для шины PCI. До недавних времен практически никогда не реализовывалось в обыкновенных x86/PCI системах, хотя в настоящее время есть тенденция к изменению этой ситуации, главным образом с целью повышения производительности гипервизоров виртуальных машин. Всегда реализовывалось для шины AGP под названием AGP GART с целью облегчить произвольный доступ видеопроцессора к текстурам, находящимся в основной памяти. Со стороны устройства данное оборудование было стандартизировано спецификацией AGP, со стороны программного обеспечения стандартизации не существовало, и реализация зависела от производителя микросхемы северного моста между AGP и памятью (отсюда необходимость в «драйвере AGP», таком, как agp440.sys для микросхем Intel). Набор вызовов ядер развитых операционных систем, таких, как Windows, всегда содержал архитектурную абстракцию IOMMU (MapTransfer и GetScatterGatherList, эти же вызовы поддерживают и bounce buffer, понимаемый как разновидность IOMMU), позволяющую одному и тому же драйверу устройства поддерживать его при присоединении через различные IOMMU.
Недостатки:
- требование сложной логики уже не в устройстве, а в платформе.

DMA и IDE/ATA, Ultra DMA

[править | править код]

Первоначальный контроллер жёсткого диска компьютера IBM PC/AT не поддерживал DMA и требовал передачи всех данных дискового ввода-вывода инструкциями REP INSW/REP OUTSW через порт 0x1f0.

В начале 1990-х годов диски MFM/RLL вышли из употребления («вымерли»), сменившись дисками IDE, но регистровый интерфейс ПО к контроллеру не изменился.

Низкая производительность такого контроллера стала серьёзной проблемой, особенно на системах PCI. Помимо требования нескольких циклов PCI на передачу каждых двух байт данных, это приводило к загрузке процессора дисковым вводом-выводом.

Для решения проблемы ряд компаний, в том числе Intel, разработал контроллеры IDE с поддержкой DMA. Контроллеры были и остаются несовместимыми по ПО между различными производителями, хотя совместимость всех Intel IDE/ATA/SATA снизу вверх более или менее поддерживается.

Также особенностью этой поддержки является использование новых команд протокола IDE/ATA, а значит, и требование поддержки DMA не только контроллером, но и самим жёстким диском.

Около 2000 года поддержка DMA по шине IDE/ATA развилась в сторону увеличения тактовой частоты шины, что потребовало нового типа кабеля от контроллера к диску с удвоенным числом проводников меньшего диаметра. Эта технология называлась «Ultra DMA» (UDMA).

Многие операционные системы требовали действий администратора для использования IDE DMA. Так, например, стандартные ядра Linux до примерно 2004 года не имели такой поддержки, требовалось пересборка ядра с отредактированным файлом конфигурации.

В семействе ОС Windows поддержка IDE DMA появилась сначала только для Intel в пакетах обновлений к ОС Windows NT 4 и требовала на большинстве систем ручного редактирования реестра для задействования.

В ОС Windows 2000 это требование исчезло, но появилось требование обязательного внесения в список и выставления режима DMA в BIOS даже незагрузочных дисков. Эти настройки становились видимы ядру ОС через технологию ACPI, и ОС не позволяла включить DMA для диска, не внесённого в список дисков BIOS. Для сравнения: ОС Windows NT 4 поддерживала и произвольный размер диска и DMA без внесения диска в список BIOS.

В ОС Linux для ручного включения или выключения IDE DMA может применяться команда hdparm (см. ниже). Современные версии ядра автоматически включают DMA-режим, что можно наблюдать в сообщениях отладки (строки вида «ata1.00: configured for UDMA/133» или «hda: UDMA/33 mode selected»).

Режимы Ultra DMA протокола ATA для ОС Linux

[править | править код]

hdparm  -i  /dev/sda
MByte/s
Mode 0 16.7 UDMA16
Mode 1 25.0 UDMA25
Mode 2 33.3 UDMA33
Mode 3 44.4 UDMA44
Mode 4 66.7 UDMA66
Mode 5 100.0 UDMA100
Mode 6 133.3 UDMA133

Примечания

[править | править код]
  1. z/OS Communications Server | Remote Direct Memory Access over Converged Ethernet(last updated in V2R1). Дата обращения: 3 августа 2019. Архивировано 3 августа 2019 года.