访问映射设备内存是否缓慢(就延迟而言)?
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 的负载,使其可以腾出时间去做其他有用的工作。)
我知道这个问题很模糊..但我希望了解的是: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 的负载,使其可以腾出时间去做其他有用的工作。)