♦ Команды конфигурационного чтения и записи адресуются к конфигурационному пространству устройств (см. п. 6.2.12). Обращение производится только двойными словами. Структура содержит идентификатор устройства и производите для, состояние и команду, информацию о занимаемых ресурсах и ограничения на использование шины. Для генерации данных команд требуется специальный аппаратно-программный механизм (см. п. 6.2.11).
♦ Чтение строк памяти применяется, когда в транзакции планируется более двух 32-битных передач (обычно это чтение до конца строки кэша).
♦ Множественное чтение памяти используется для транзакций, пересекающих границы строк кэш-памяти.
♦ Запись с инвалидацией применяется к целым строкам кэша и позволяет оптимизировать циклы обратной записи «грязных» строк кэша.
♦ Двухадресный цикл позволяет по 32-битной шине обращаться к устройствам с 64-битной адресацией. В этом случае младшие 32 бита адреса передаются в цикле данного типа, а за ним следует обычный цикл, определяющий тип обмена и несущий старшие 32 бита адреса. Шина PCI допускает 64-битную адресацию портов ввода-вывода (для х86 это бесполезно, но PCI существует и на других платформах).
Таблица 6.12. Декодирование команд шины PCI
С/BE[3:0] |
Тип команды |
0000 |
Interrupt Acknowledge — подтверждение прерывания |
0001 |
Special Cycle — специальный цикл |
0010 |
I/O Read — чтение порта ввода-вывода |
0011 |
I/O Write — запись в порт ввода-вывода |
0100 |
Зарезервировано |
0101 |
Зарезервировано |
0110 |
Memory Read — чтение памяти |
0111 |
Memory Write — запись в память |
1000 |
Зарезервировано |
1001 |
Зарезервировано |
1010 |
Configuration Read — конфигурационное считывание |
1011 |
Configuration Write — конфигурационная запись |
1100 |
Multiple Memory Read — множественное чтение памяти |
1101 |
Dual Address Cycle (DAC) — двухадресный цикл |
1110 |
Memory-Read Line — чтение строки памяти |
1111 |
Memory Write and Invalidate — запись с инвалидацией |
6.2.5. Пропускная способность шины
Шина PCI является самой высокоскоростной шиной расширения современных ПК, однако и ее реальная пропускная способность, увы, не так уж и высока. Рассмотрим наиболее распространенный вариант: разрядность 32 бита, частота 33 МГц. Как указывалось выше, пиковая скорость передачи данных внутри пакетного цикла составляет 132 Мбайт/с, то есть за каждый такт шины передаются 4 байта данных (33×4=132). Однако пакетные циклы выполняются далеко не всегда. Процессор общается с устройствами PCI инструкциями обращения к памяти или вводу-выводу через главный мост, который шинные транзакции процессора транслирует в транзакции шины PCI. Поскольку у процессоров х86 основные регистры 32-разрядные, то одна инструкция порождает транзакцию с устройством PCI, в которой передается не более 4 байт данных, что соответствует одиночной передаче. Если же адрес передаваемого (двойного) слова не выровнен по соответствующей границе, то будут порождены два одиночных цикла или один пакетный с двумя фазами данных, но в любом случае это обращение будет выполняться дольше, чем при выровненном адресе.
Однако при записи массива данных в устройство PCI (передача с последовательно нарастающим адресом) мост может пытаться организовать пакетные циклы. У современных процессоров (начиная с Pentium) шина данных 64-битная и применяется буферизация записи, так что два последовательных 32-битных запроса записи объединятся в один 64-битный. Этот запрос, если он адресован к 32-битному устройству, мост попытается передать пакетом с двумя фазами данных. «Продвинутый» мост может пытаться собирать в пакет и последовательные запросы, что может породить пакет существенной длины. Пакетные циклы записи можно наблюдать, например, передавая массив данных из ОЗУ в устройство PCI строковой инструкцией MOVSD
, используя префикс повтора REP
. Тот же эффект даст и цикл последовательных операций LODSW
, STOSW
(и иных инструкциях обращения к памяти). Поскольку у современных процессоров ядро исполняет инструкции гораздо быстрее, чем шина способна вывести их результаты, между инструкциями, порождающими объединяемые записи, процессор может успеть выполнить еще несколько операций. Однако если пересылка данных организуется директивой языка высокого уровня, которая ради универсальности работает гораздо сложнее вышеприведенных ассемблерных примитивов, транзакции, скорее всего, будут уже одиночными (у буферов записи процессора не хватит «терпения» придержать один 32-битный запрос до появления следующего, или же произойдет принудительная выгрузка буферов записи процессора или моста по запросу чтения, см. п. 6.2.10).
Читать дальше