Медленен ли доступ к памяти сопоставленного устройства (с точки зрения задержки)?

Я знаю, что вопрос расплывчатый ... но вот что я надеюсь узнать: MCU направляет некоторую часть адреса памяти устройствам на шине PCI, поэтому теоретически код пользователя / ядра может напрямую читать / записывать память устройства, как если бы это было основная память. Но данные, входящие и исходящие из устройств PCI Express, упаковываются/сериализуются/передаются по дорожкам, что означает, что каждое чтение/запись влечет за собой значительные накладные расходы, такие как упаковка (добавление заголовков) и распаковка. Таким образом, это означает, что пользователю/ядру не идеально считывать память устройства побайтно, вместо этого он должен выполнять какую-то массовую передачу. Если да, то какой предпочтительный механизм и API?

Кстати, я знаю, что есть DMA, но мне кажется, что DMA не требует, чтобы память устройства была напрямую отображена в адресное пространство основной памяти - DMA предназначен для предоставления устройству доступа к основной памяти, и мой вопрос заключается в другом, позволяя пользователю/ память устройства доступа к ядру. Итак, я предполагаю, что это не связано с вопросом выше, верно?


person QnA    schedule 31.12.2019    source источник
comment
Единственный разумный ответ — это зависит — и это зависит от многих факторов (о большинстве из которых я, вероятно, не знаю).   -  person Jonathan Leffler    schedule 01.01.2020
comment
Вы правы, что DMA касается устройства, обращающегося к основной памяти. Это несколько связано с вашим вопросом, как я уже упоминал в своем ответе.   -  person prl    schedule 01.01.2020
comment
нашел эту ссылку полезной stackoverflow.com/a/36463477/2762678   -  person QnA    schedule 05.01.2020


Ответы (1)


Да, доступ к вводу-выводу с отображением памяти (MMIO) медленный.

Основная причина его медленности заключается в том, что он, как правило, не кэшируется, поэтому каждый доступ должен идти до самого устройства. В системах x86, с которыми я больше всего знаком, доступ к кэшируемой памяти осуществляется блоками по 64 байта, хотя инструкции процессора обычно обращаются к памяти блоками по 1, 2, 4 или 8 байт. Если несколько инструкций процессора обращаются к соседним кэшируемым ячейкам памяти, все обращения, кроме первого, выполняются из кэша. При аналогичном доступе к памяти устройства каждый доступ вызывает полную задержку до устройства и обратно.

Вторая причина заключается в том, что пути от процессоров к памяти критичны для производительности и сильно оптимизированы. Путь к устройствам всегда был медленным, поэтому программное обеспечение предназначено для компенсации этого, и оптимизация производительности MMIO не является приоритетом.

Другая связанная с этим причина заключается в том, что PCI имеет правила упорядочения, которые требуют буферизации и обработки доступов в строгом порядке. Система памяти может управлять упорядочением гораздо более гибким образом. Например, грязная строка кэша может быть записана в память в любое удобное время. Доступы MMIO должны выполняться точно в том порядке, в котором они выполняются ЦП.

Лучший способ выполнить массовую передачу данных на устройство — заставить само устройство выполнять DMA, «извлекая» данные из памяти в устройство, а не «выталкивая» их из ЦП на устройство. (Это также снижает нагрузку на ЦП, освобождая его для выполнения другой полезной работы.)

person prl    schedule 01.01.2020
comment
Спасибо, @prl. Лучший способ выполнить массовую передачу данных на устройство — заставить само устройство выполнять DMA — тогда почему устройства PCIe вообще имеют отображение памяти? Если бы они отображали несколько байтов и использовали их в качестве управляющих регистров, это было бы понятно, но они могут отображать больше, чем несколько мегабайт. - person QnA; 04.01.2020