SATA и AHCI изнутри: команды, FIS, NCQ и путь запроса к накопителю

ATA определяет действие, SATA переносит обмен, а AHCI позволяет драйверу управлять совместимым HBA через регистры и память. Открыть иллюстрацию в полном размере.
SATA-накопитель сообщает о соединении 6 Гбит/с, но файл копируется медленнее 600 МБ/с. При увеличении очереди SSD обслуживает больше операций, хотя провод и режим линии остаются прежними. После простоя первый запрос задерживается, а следующие выполняются быстрее. Для объяснения этих наблюдений нужно разделить физическую передачу, команды накопителя и работу контроллера с памятью компьютера.
AHCI предоставляет программный интерфейс к контроллеру, SATA переносит обмен по последовательному соединению, а ATA задаёт команды и их смысл. Ниже прослежен путь запроса через эти уровни. Все числовые сценарии являются учебными. Они не представляют измерения конкретного диска и не требуют менять режим контроллера, форматировать накопитель или выполнять другие операции с пользовательскими данными.
Содержание статьи
- ATA, SATA и AHCI находятся на разных уровнях
- Запрос приложения не равен одной ATA-команде
- AHCI-контроллер работает с портами и памятью регистров
- Список команд указывает на таблицы, а не хранит весь запрос
- PRDT описывает разрозненные области данных для DMA
- FIS разделяют команды, данные и сообщения о состоянии
- Путь чтения связывает подготовку, передачу и завершение
- Запись в устройство и долговременное сохранение различаются
- NCQ даёт устройству несколько команд на выбор
- Один механизм очереди помогает HDD и SSD по-разному
- Глубина очереди связана со временем ответа
- Почему SATA 6 Гбит/с не означает 600 МБ/с файлов
- Логический сектор определяет смысл адреса LBA
- Ошибка линии не равна ошибке поверхности или NAND
- Энергосостояния могут добавлять задержку после простоя
- Переходник или общий порт добавляют новую границу
- AHCI и NVMe нельзя различать только по форме разъёма
- Как построить содержательную проверку производительности
- Официальные первичные источники
- Читайте также
ATA, SATA и AHCI находятся на разных уровнях
ATA описывает команды вроде чтения, записи и получения сведений об устройстве. SATA определяет последовательный обмен между узлами и связанные механизмы передачи. AHCI описывает, каким образом программа управляет совместимым хост-контроллером через регистры и структуры в системной памяти. Поэтому фраза «накопитель работает по AHCI» обычно сокращает целую цепочку отношений, а не называет электрический протокол кабеля.
Контроллер принимает подготовленное программой описание команды, формирует нужный обмен с устройством и перемещает данные через DMA. Он не обязан быть отдельной микросхемой на видимой плате расширения: функции могут находиться в чипсете или другом интегрированном блоке. Критично то, какой интерфейс реально представлен ОС, какие порты существуют и какие возможности объявлены конкретной реализацией.
AHCI 1.3.1 Intel служит первичным определением этого программного интерфейса. Поддержка SATA устройством не означает автоматического использования AHCI любым переходником: внешний USB-мост может показывать системе другой интерфейс и переводить команды самостоятельно. Разделение уровней помогает понять, где искать ограничение и какие сведения видит драйвер.
Запрос приложения не равен одной ATA-команде
Приложение обычно работает с файлом, файловая система переводит его области в блоки, а подсистема хранения организует запросы к устройству. Между приложением и диском могут находиться кэш, объединение соседних операций, очередь и дополнительные слои. Поэтому одно чтение программы способно вообще не дойти до накопителя либо превратиться в несколько команд. Сопоставлять число вызовов программы с количеством FIS без проверки нельзя.
Операционная система также определяет порядок и приоритеты с учётом собственных правил. Контроллер получает уже подготовленные операции, но не знает полного смысла файла или базы данных. Для него адрес блока и длина передачи являются техническими параметрами, а не названием документа. Гарантии порядка и сохранности формируются совместно несколькими уровнями, поэтому отдельный успешный аппаратный обмен ещё не описывает завершение пользовательской транзакции.
Руководство libATA показывает пример реальной организации драйверного слоя Linux, включая поддержку контроллеров и преобразование между представлениями команд. Это конкретная программная реализация, а не обязательная внутренняя структура любой ОС. При анализе задержки полезно отдельно учитывать ожидание до выдачи команды, её обслуживание устройством и передачу результата обратно приложению.
AHCI-контроллер работает с портами и памятью регистров
Программа обнаруживает контроллер как системное устройство, получает доступ к его области регистров и определяет реализованные возможности. AHCI предусматривает несколько портов, но максимальное число в архитектуре не означает, что каждый контроллер или компьютер имеет столько физических разъёмов. Карта реализованных портов и поля возможностей задают доступный набор. Поддержка расширений также проверяется отдельно.
Регистры порта содержат адреса служебных структур, управляющее состояние и сведения о текущих событиях. Изменение определённого бита может сообщить контроллеру о новой команде, однако полезные данные не нужно записывать в тот же регистр по одному слову. Это различие принципиально: управляющий обмен относительно мал, а большие массивы перемещаются через описанные в памяти буферы.
У разных режимов представления контроллера могут быть разные драйверы и ожидания загрузочной ОС. Из архитектурного описания не следует совет переключать режим прошивки на работающей системе ради эксперимента. Такой шаг способен изменить доступность системного диска. Для информационного анализа достаточно установить фактический драйвер, возможности контроллера и текущий режим без произвольного изменения конфигурации.
Список команд указывает на таблицы, а не хранит весь запрос
Для обычного порта AHCI список команд содержит до 32 заголовков по 32 байта. Полная область такого списка занимает 1024 байта; требуемое выравнивание является отдельным условием спецификации. Реально доступное число командных слотов определяется возможностями HBA. Поэтому рисунок с 32 позициями не означает, что любая реализация обязана одновременно обслуживать именно 32 полезные операции приложения.
Заголовок содержит параметры команды и указатель на command table. В таблице находится исходящий Command FIS, область для предусмотренного ATAPI-обмена и список описателей буферов данных. Эти структуры имеют разные назначения и размеры. Полезный блок на сотни килобайт не помещают внутрь 32-байтного заголовка: заголовок лишь связывает управляющую информацию с остальной памятью.
Разделение структур позволяет контроллеру читать нужные сведения и выполнять обмен без программной отправки каждого байта. Но оно требует корректного времени жизни памяти, видимости записей и соблюдения порядка взаимодействия с устройством. Драйвер не может освободить таблицу сразу после выдачи команды, если HBA ещё обращается к ней. Ошибка этого уровня способна выглядеть как сбой накопителя, хотя сам носитель исправен.

PRDT описывает разрозненные области данных для DMA
Physical Region Descriptor Table, PRDT, содержит элементы scatter/gather: где находится очередной участок буфера и сколько байтов нужно передать. Одна логическая операция может использовать несколько физических диапазонов памяти. Благодаря описателям контроллер связывает эти участки с одним запросом, а программа не обязана заранее складывать весь массив в единственную непрерывную физическую область только ради формата команды.
В AHCI один PRD занимает 16 байт. Для учебной передачи 128 КиБ, разбитой на четыре участка по 32 КиБ, четыре описателя занимают 64 байта. Полезные 131072 байта находятся в самих буферах. Это разные объёмы: описание передачи не является её содержимым. Реальный драйвер может объединять соседние диапазоны или создавать другое число элементов в пределах аппаратных ограничений.
Направление DMA нужно читать относительно данных. При чтении накопителя HBA записывает полученные байты в память хоста. При записи накопителя HBA читает исходные байты из памяти хоста и отправляет устройству. Защита и перевод DMA-адресов могут включать IOMMU, но адрес в аппаратном описателе всё равно нельзя бездумно подменять обычным виртуальным указателем процесса.

FIS разделяют команды, данные и сообщения о состоянии
Frame Information Structure, FIS, является форматом обмена информацией через SATA. Register Host-to-Device FIS переносит поля команды от хоста к устройству. Другие типы предназначены для состояния, настройки DMA, данных и сообщений, связанных с завершением. Поэтому FIS не является единственной универсальной коробкой, в которой всегда лежит целый пользовательский запрос со всеми его данными.
Например, Register H2D FIS имеет компактный формат 20 байт. Большая передача проходит отдельными порциями данных и связанными действиями протокола. Тот факт, что команда описана короткой структурой, не означает ограничение размера чтения двадцатью байтами. Нужно различать длину управляющего сообщения, размер блока данных и суммарный объём, который обслуживает операция.
AHCI также предусматривает область Received FIS в системной памяти. Для обычного случая порта она занимает 256 байт и имеет заданное выравнивание; расширенные режимы могут отличаться. Это служебная область для принятых структур, а не кольцо со всем содержимым прочитанных файлов. Полезные данные поступают в буферы, описанные через PRDT, поэтому наличие двух адресов памяти не означает их бессмысленное дублирование.
Путь чтения связывает подготовку, передачу и завершение
Сначала драйвер выделяет свободный слот, подготавливает заголовок, Command FIS и описатели целевых буферов. После выполнения необходимых условий видимости он сообщает HBA о готовой работе. Контроллер получает описание и отправляет командный обмен на порт. Накопитель обрабатывает запрос с учётом собственных очередей, кэша и состояния носителя. Это последовательность событий, а не единственное мгновенное действие.
Когда устройство передаёт данные, HBA размещает их в подготовленных областях системной памяти. Затем аппаратное состояние сообщает о завершении или ошибке, а драйвер сопоставляет событие с соответствующей операцией. Он проверяет результат и только после соблюдения необходимых условий возвращает буфер верхним слоям. Уведомление о событии и готовность пользовательского приложения обработать его также разделены планировщиком.
Часть обработки может перекрываться с другими командами. Однако конкретный запрос нельзя объявить успешным только по тому, что на линии были данные или загорелся индикатор активности. Нужны корректное завершение, ожидаемая длина и отсутствие соответствующих ошибок. Такая модель помогает отделять отсутствие команды от проблемы передачи и от задержки приложения после уже завершённого аппаратного запроса.
Уведомления также не обязаны соответствовать командам в отношении один к одному. Контроллер и драйвер могут использовать предусмотренное объединение событий, а программная обработка — забирать сразу несколько готовых результатов. Это уменьшает частоту обслуживания, но способно менять задержку уведомления. Сравнивая режимы, полезно различать момент аппаратного завершения и момент, когда драйвер действительно заметил его и вернул результат верхнему слою.

Запись в устройство и долговременное сохранение различаются
При записи источник находится в системной памяти. Контроллер перемещает данные к накопителю согласно протоколу и подготовленным описателям. Но устройство может иметь энергозависимый кэш, а верхние слои — собственные очереди. Поэтому успешная передача байтов и гарантия пережить внезапное отключение питания относятся к разным границам. Значение завершения определяется командой и действующими правилами всего стека.
Существуют команды управления кэшем и средства запроса необходимого поведения, если они поддерживаются устройством. Например, руководство Seagate SkyHawk 100844776 Rev. B перечисляет поддерживаемые ATA-команды, включая Flush Cache и Flush Cache Extended. Это пример документирования конкретной модели, а не утверждение об одинаковых возможностях всех накопителей.
ОС и приложение должны использовать нужную семантику согласованно. Нельзя самостоятельно заменить её рассуждением «DMA закончился, значит файл навсегда сохранён». Также ошибочно считать, что отключение любого кэша автоматически является оптимальной настройкой надёжности и скорости. Требуется понимать требования приложения, фактическую поддержку команд и границы защиты питания, сохраняя пользовательские данные при проверке.
Порядок нескольких записей тоже имеет смысл, отличный от успешной доставки каждой по отдельности. Приложению может быть необходимо сначала сохранить данные, затем связанное описание их состояния. Командная очередь не знает этой логики автоматически. Файловая система и приложение выражают требования своими средствами, а драйвер переводит их в поддерживаемые операции. Поэтому проверка устойчивости данных требует всего пути и не заменяется тестом средней полосы SATA.
NCQ даёт устройству несколько команд на выбор
Native Command Queuing позволяет хранить несколько незавершённых команд с идентификаторами и выбирать порядок их обслуживания. Для классического SATA NCQ пространство тегов связано с пределом 32 команды, однако фактически поддерживаемая глубина устройства и контроллера может быть меньше. Тег отличает операцию от соседних, но не является отдельным физическим каналом передачи данных.
Устройство способно завершать команды в порядке, отличающемся от выдачи, в пределах правил их класса и зависимостей. Программа не должна предполагать, что первый отправленный запрос всегда первым вернёт результат. При этом переупорядочивание не разрешает игнорировать необходимые требования к данным. Запросы, между которыми приложение установило зависимость, должны согласовываться механизмами более широкого стека хранения.
Таблица AHCI и очередь NCQ также не тождественны. Слот существует на стороне хост-контроллера, а очередь команд — в модели SATA-устройства. Между ними есть связь, но поддержка многих слотов не превращает произвольную неочередную ATA-команду в NCQ. Полезно проверять, какие команды действительно используются, а не делать вывод по одному числу глубины очереди в программе тестирования.

Один механизм очереди помогает HDD и SSD по-разному
На жёстком диске выбор порядка может уменьшать механические перемещения и ожидание нужных участков. Если устройство видит несколько независимых запросов, оно получает больше вариантов эффективного обслуживания. Это не означает одинаковое ускорение каждого запроса: приоритеты и расположение данных различаются, а долго ожидающая операция может получить дополнительную задержку ради лучшей суммарной обработки.
У SSD нет движущихся головок, но существуют внутренние ресурсы NAND, контроллер, кэш и фоновые операции. Несколько команд способны раскрыть параллелизм, который одиночная зависимая операция не использует. Однако внешний SATA-канал остаётся общим. Очередь не умножает полосу линии на число тегов и не отменяет ограничения записи или чтения самого накопителя.
При малом количестве независимой работы увеличение настроенного предела очереди вообще может ничего не изменить: нечего дополнительно отправлять. При перегрузке большое число ожидающих операций поднимает задержку. Поэтому правильное сравнение учитывает не только IOPS, но и время ответа, характер доступа и фактическое число незавершённых запросов. Паспортный максимум очереди не является обязательной целью для любого приложения.
Глубина очереди связана со временем ответа
Для устойчивой системы среднее число незавершённых запросов L связано со средней скоростью завершения λ и средним временем запроса W выражением L = λW. Границы измерения должны совпадать: если в W включено ожидание в очереди ОС, L тоже должно охватывать эту область. Настроенный предел очереди не обязательно равен фактическому среднему L.
В учебном сценарии 40 тысяч операций в секунду и 200 мкс среднего времени соответствуют L = 8. Если та же скорость сохраняется при среднем L = 32, время возрастает до 800 мкс. Это арифметическая связь средних величин, а не обещание, что каждый запрос имеет ровно такую задержку. Для интерактивной задачи редкие длинные ожидания могут быть важнее среднего значения.
Если увеличение очереди почти перестало поднимать скорость, дальнейший рост способен в основном добавлять ожидание. Это признак насыщения выбранного пути, но ещё не диагноз конкретного блока. Ограничение может находиться в линии, устройстве, общей связи контроллера с системой или приложении. График нагрузки нужно интерпретировать вместе с размером операций и физическим маршрутом данных.

Почему SATA 6 Гбит/с не означает 600 МБ/с файлов
Для SATA 6 Гбит/с применяется кодирование 8b/10b: десять переданных битов соответствуют восьми битам закодированных данных. Арифметический предел до дальнейших расходов равен 6·109 × 8/10 / 8 = 600·106 байт/с. Служебный обмен, кадрирование, паузы и поведение устройства уменьшают полезный результат. Это ещё не скорость файловой системы.
Для масштаба передача 4 КиБ при 600 МБ/с занимает 6,83 мкс, а 1 МиБ —1,75 мс. Все объёмы здесь двоичные и явно переведены в байты. Но отдельное чтение включает дополнительные этапы до появления первого полезного байта. Поэтому деление размера на полосу объясняет лишь один вклад и не позволяет вывести полную задержку случайной операции по характеристике линии.
У HDD длительный поток может ограничиваться механикой и плотностью записи, у SSD — NAND, кэшем, фоновыми операциями или самим SATA-путём. При копировании между двумя устройствами добавляются оба конца, память и программная обработка. Сравнивать нужно одинаковую полезную нагрузку и способ подсчёта байтов, сохраняя различие между Гбит/с, МБ/с и МиБ/с.
Логический сектор определяет смысл адреса LBA
Команда адресует логические блоки, а их размер является свойством представления устройства. Для 512-байтного логического сектора LBA 2048 соответствует смещению 1048576 байт, то есть 1 МиБ. Если логический сектор 4096 байт, тот же номер блока означает уже 8 МиБ. Поэтому число LBA без размера сектора не задаёт абсолютное смещение в байтах.
У 512e-устройства логический сектор может быть 512 байт, а физическая организация —4096 байт. Тогда восемь логических секторов соответствуют одному такому физическому диапазону. Неполная или неудачно выровненная запись способна потребовать дополнительной внутренней работы, хотя размер команды на интерфейсе остаётся прежним. Точные последствия зависят от реализации и состояния кэша, а не выводятся из одной аббревиатуры.
Это не повод вручную менять разметку действующего диска ради проверки. Для объяснения поведения достаточно корректно прочитать объявленные размеры и сопоставить их с рабочей нагрузкой. Файловая система, разделы, драйвер и мост могут добавлять свои единицы представления. В техническом описании полезно сохранять все эти границы, чтобы не перепутать размер команды с физической гранулярностью носителя.

Ошибка линии не равна ошибке поверхности или NAND
Передаваемый обмен имеет средства обнаружения нарушений, а устройство отдельно сообщает ошибки выполнения команд. Проблема кабеля или контакта относится к другому пути, чем невозможность прочитать данные с носителя. Сходное сообщение приложения может скрывать разные аппаратные причины. Для локализации важны тип события, состояние контроллера, сведения накопителя и повторяемость в согласованных условиях.
Сбой в очереди NCQ способен потребовать дополнительных действий для определения проблемной команды и восстановления состояния порта. Руководство libATA подробно рассматривает обработку ошибок как отдельную часть драйвера. Сброс или повтор не означает ремонта физического носителя: это способ привести протокол в согласованное состояние либо повторно выполнить допустимую операцию. Приоритетом остаётся сохранение данных и корректная оценка причины.
Счётчик обнаруженных ошибок нужно читать с определением и контекстом модели. Нельзя по одному необнулённому историческому значению уверенно объявить текущий кабель неисправным. Так же неверно считать отсутствие записи в одном счётчике гарантией исправности всего пути. Полезна динамика при повторяемом опыте, сопоставленная с журналом событий и неизменными условиями нагрузки.
Энергосостояния могут добавлять задержку после простоя
У SATA-линии есть состояния экономии энергии, а у накопителя и системного устройства — собственные режимы. Переход в более глубокий простой уменьшает расход, но возвращение к активной работе занимает время. Поэтому первый запрос после паузы способен отличаться от следующего потока даже без изменения характеристик носителя. Нужно уточнять, какой именно элемент просыпается.
Документация Microsoft SATA/AHCI описывает управление Partial, Slumber и DEVSLP драйвером StorAHCI в указанной среде. Это пример конкретной политики, а не универсальное расписание всех ОС. Нельзя переносить приведённый таймер на любой контроллер или считать, что одинаковое название состояния гарантирует одинаковое время пробуждения устройства.
При измерении полезно отдельно фиксировать холодный запрос после простоя и установившийся поток. Отключение энергосбережения не является автоматическим исправлением любой задержки: оно меняет потребление, а причина может находиться в другом месте. Информационная модель нужна, чтобы различать вклад перехода состояний и работу носителя, а не рекомендовать бездоказательное изменение настроек.
Переходник или общий порт добавляют новую границу
USB—SATA-мост принимает обмен с одной стороны и формирует SATA-команды с другой. ОС может видеть другой драйвер и другую модель очередей, чем при прямом AHCI-подключении. Пропускная способность и доступность отдельных команд зависят от моста и выбранного USB-протокола. Поэтому одинаковый накопитель в разных корпусах не обязан показывать идентичную задержку и набор диагностических сведений.
Некоторые SATA-конфигурации используют port multiplier, если его поддерживает контроллер и остальная система. Несколько устройств тогда разделяют соответствующий путь, а не получают независимую полосу магически из одного соединения. Наличие такого механизма проверяется по возможностям HBA; число физических разъёмов на переходной плате ещё не описывает независимость внутренних каналов.
При сравнении прямого подключения и переходника нужно сохранить накопитель, данные, режим нагрузки и состояние кэша. Изменение результата само по себе не доказывает ухудшение носителя: изменился маршрут. Разделение границ помогает определить, какую характеристику измерили — SATA-устройство, мост, внешний интерфейс или полный пользовательский путь.
Ещё одна граница возникает на стороне подключения контроллера к остальной системе. Несколько портов способны иметь независимые SATA-линии, но разделять общий восходящий путь или внутренние ресурсы HBA. Тогда сумма одновременных потоков ограничивается иначе, чем одиночный тест каждого диска. Для оценки важно сопоставлять топологию с реально измеренной совокупной нагрузкой, не обещая каждому порту его максимум одновременно при любых обстоятельствах.
AHCI и NVMe нельзя различать только по форме разъёма
AHCI организован вокруг определённой модели портов и командных структур для совместимых контроллеров. NVMe предлагает другую модель команд и очередей. Это различие программного интерфейса не сводится к размеру корпуса накопителя. В частности, форм-фактор M.2 способен встречаться с разными интерфейсами; совместимость определяется устройством, разводкой и возможностями слота.
Microsoft описывает StorAHCI как драйвер для AHCI-контроллеров, исторически сменивший MSAHCI. Имя драйвера относится к способу обслуживания контроллера ОС, а не к типу ячеек внутри SSD. NAND-накопитель может работать через SATA/AHCI, сохраняя ту же внешнюю модель команд, что и механический диск.
Полезное сравнение протоколов начинается с реально нужной задачи: глубины и числа очередей, пути DMA, требований к задержке и ограничений устройства. Само наличие более новой модели команд не гарантирует одинакового выигрыша каждого приложения. Но корректное разделение ATA, SATA, AHCI и NVMe позволяет объяснить, какие архитектурные границы меняются, а какие остаются свойствами самого носителя.
Как построить содержательную проверку производительности
Сначала фиксируют модель устройства, логический сектор, режим линии, контроллер и драйвер, наличие моста и состояние очередей. Затем определяют полезную операцию: размер, направление, случайность, зависимости и длительность. Только после этого сравнивают IOPS, полосу и задержки. Одна большая цифра последовательного чтения не описывает поведение коротких зависимых запросов и не проверяет долговременное сохранение записи.
Следует отличать чтение из кэша ОС, кэша накопителя и носителя. Повторение одного и того же диапазона может менять измеряемый путь, даже когда программа показывает одинаковую команду запуска. Для записи особенно важно знать фактическую длительность и объём: короткий опыт способен поместиться в кэш и не показать установившееся поведение. Такие границы нужно явно сообщать вместе с результатом.
Полная модель связывает команду, описатели памяти, обмен FIS, действия устройства и завершение в программе. Она позволяет понять, почему очередь помогает, где появляются служебные расходы и почему 600 МБ/с не являются обещанием скорости любого файла. Такой разбор полезнее универсального совета заменить кабель или увеличить очередь: сначала он устанавливает, какой участок действительно ограничивает работу.
Официальные первичные источники
- Intel — Serial ATA AHCI 1.3.1 Specification: программный интерфейс HBA и структуры команд.
- Linux Kernel — libATA Developer’s Guide: драйверный слой и обработка ошибок.
- Seagate — SkyHawk SATA Product Manual 100844776 Rev. B: пример объявленных возможностей и команд модели.
- Microsoft — StorAHCI replaces MSAHCI: роль драйвера AHCI в описанной системе.
- Microsoft — SATA/AHCI: пример политики энергосостояний хранения.