访问映射设备内存是否缓慢(就延迟而言)?

Is accessing mapped device memory slow (in terms of latency)?

我知道这个问题很模糊..但我希望了解的是:MCU将内存地址的一部分指向PCI总线上的设备,因此理论上user/kernel代码可以直接read/write 设备内存就好像它是主内存一样。但是 PCI Express 设备的数据进出是 packaged/serialized/transmitted 通道,这意味着每个 read/write 都会产生显着的开销,例如打包(添加 headers)和 un-packaging。所以这意味着 user/kernel 一次读取一个字节的设备内存并不理想,而应该进行某种批量传输。如果是这样,首选机制是什么 API?

顺便说一句,我知道有DMA,但在我看来,DMA不需要设备内存直接映射到主内存地址space - DMA是让设备访问主内存,而我的问题是另一种方式,让 user/kernel 访问设备内存。所以我猜这与上面的问题无关,对吗?

是的,访问内存映射 I/O (MMIO) 很慢。

它速度慢的主要原因是它通常是不可缓存的, 所以每次访问都必须一直到设备。 在我最熟悉的 x86 系统中,可缓存内存以 64 字节块的形式访问, 尽管处理器指令通常以 1、2、4 或 8 字节块的形式访问内存。 如果多个处理器指令访问相邻的可缓存内存位置,则除了第一个访问之外的所有访问都从缓存中得到满足。对于对设备内存的类似访问,每次访问都会导致设备来回的完全延迟。

第二个原因是从处理器到内存的路径对性能至关重要,并且经过高度优化。 通往设备的路径一直很慢,因此软件旨在弥补这一点,优化 MMIO 的性能并不是优先事项。

另一个相关的原因是 PCI 有排序规则,要求访问以严格的顺序缓冲和处理。 内存系统可以以更灵活的方式处理排序。例如,脏缓存行可能会在任何方便的时候写入内存。 MMIO 访问必须严格按照 CPU.

执行的顺序执行

将数据批量传输到设备的最佳方法是让设备本身执行 DMA,"pulling" 将数据从内存传输到设备,而不是 "pushing" 从 CPU 到设备。 (这也减少了 CPU 的负载,使其可以腾出时间去做其他有用的工作。)