来自PCIe内存的Memcpy比memcpy花费更多时间到PCIe内存

时间:2017-01-31 13:59:28

标签: memory linux-kernel linux-device-driver pci-e

我正在尝试从/向PCIe 2.0(2通道)设备向/从Linux PC读取/写入数据。用于读写的存储器位于PCIe设备中的不同RAM位置。这些内存使用ioremap映射到Linux PC中。我的用例是实现18MBytes /秒的读/写吞吐量,这显然是由PCIe链路支持的。 PCIe设备的内存未缓存。

我能够实现写吞吐量,即当我使用memcpy从Linux PC本地内存写入PCIe设备内存时。在这种情况下,对于9216字节的数据,memcpy花费不到1 ms。但是,当我将ioremapped PCIe内存读取到Linux本地内存时,数据丢失正在发生。我描述了memcpy,它需要超过1毫秒,有时2毫秒,9216字节的数据。我不想为此操作执行DMA。

关于这种情况下可能出现什么问题的任何想法?我怎么处理这个?

1 个答案:

答案 0 :(得分:0)

这是完全可以预期的,对此您无能为力。 CPU只能发出串行字大小的读取和写入,由于协议开销,PCIe链路的吞吐量非常差。每个操作都具有与其相关的24或28字节时间的开销-这是12或16字节的TLP头加上12字节时间的链路层开销,并且CPU一次只能操作4或8字节。 ..最好的情况是25%的效率(8 /(8 + 24)= 25%),最坏的情况下是12.5%的效率(4 /(4 + 28)= 12.5%)。

但是,协议开销并不是唯一的问题。 PCIe中的写操作已发布,因此CPU可以简单地发出一系列背对背写操作,这些写操作最终会进入总线和设备。另一方面,在读取时,CPU只能发出一个读取操作,等待它遍历总线两次,存储结果,再发出另一个读取,等等。由于一次只能操作8个字节,因此CPU由于PCIe总线上的相对较高的延迟(每次传输的时间大约为微秒),因此性能令人恐惧。

解决方案?使用DMA。 PCIe专为支持总线上的高效DMA操作而设计,因为设备可以发出更大的读取和写入操作,每个操作最少可读取128个字节。