我正在尝试从PCIe 2.0 (2通道)设备读取数据到Linux,或者从Linux向Linux2.0(2通道)设备写入数据。用于读取和写入的存储器位于PCIe设备中不同的随机存取存储器位置。这些内存在Linux PC上使用ioremap进行映射。我的用例是实现18MB/秒的读/写吞吐量,这显然得到了PCIe链路的支持。PCIe设备处的内存未缓存。
我能够达到写吞吐量,即当我使用memcpy从Linux本地内存写入PCIe设备内存时。在这种情况下,对于9216字节的数据,memcpy花费的时间不到1ms。但是当我读取映射到Linux本地内存的PCIe内存时,数据丢失了。我分析了memcpy,它花费了超过1ms的时间,有时9216字节的数据需要2ms。我不想为这个操作做DMA。
对于这种情况下会出现什么问题,有什么想法吗?我该怎么处理呢?
发布于 2019-07-17 07:31:52
这完全是意料之中的,你对此无能为力。中央处理器只能发出串行化的字大小的读取和写入,由于协议开销,这些读取和写入在PCIe链路上的吞吐量非常低。每个操作具有24或28字节倍的相关开销-即12或16字节的TLP头加上12字节倍的链路层开销,并且在time....which下CPU只能操作4或8字节在最佳情况下是25%的效率(8/(8+24) = 25%),最坏的情况是12.5%的效率(4/(4+28) = 12.5%)。
然而,协议开销并不是唯一的问题。PCIe中的写操作是posted的,所以CPU可以简单地发出一组背靠背的写操作,这些写操作最终会进入总线并到达设备。另一方面,当读取时,中央处理器只能发出单个读取操作,等待它遍历总线两次,存储结果,发出另一个读取,等等。由于它一次只能操作8个字节,由于PCIe总线上的相对较高的等待时间(对于每次传输可以是微秒量级),性能是可怕的。
解决方案是什么?使用DMA。PCIe是专门为支持总线上的高效直接存储器存取操作而设计的,因为设备可以发出更大的读写操作,每个操作最少可达128字节。
https://stackoverflow.com/questions/41959436
复制相似问题