我正面临一个让我头疼的问题。很受欢迎的想法/建议......
我当前的项目是执行图像分析的设备。图像由连接到FPGA的相机捕获。 FPGA通过PCI连接到具有1GB内存的i.MX6Q处理器(四核ARM Cortex-A9)。 FPGA使用DMA将图像传输到CPU存储器,CPU执行图像分析。
设备将扫描样本,获取appr。 300张图片。在分析过程中,大约50张图像需要同时存在于CPU内存中。每张图片的大小为5MB。
当前设计采用自定义Linux设备驱动程序,该驱动程序使用dma_alloc_coherent()分配单个连续DMA缓冲区。 FPGA通过DMA将每个图像传输到该缓冲区,然后将图像复制到由用户空间应用程序分配的图像缓冲池中。复制操作是一个简单的memcpy()。 应该提到的是,我们的FPGA DMA控制器不支持分散/聚集功能。因此,需要将物理上连续的缓冲区作为DMA操作的目标。
目前的解决方案原则上是有效的,但性能并不令人满意,需要改进。
我们面临的主要问题是内存带宽明显存在瓶颈。将数据从dma_alloc_coherent()分配的缓冲区移动到标准malloc缓冲区的memcpy()操作仅产生appr。 80MB /秒。
我在网上搜索了这个主题,并发现其他报告表明同样的问题。我的理解是使用DMA相干缓冲区可以有效地禁用CPU缓存。谁能证实这种理解?这是与ARM和/或i.MX6处理器特别相关的限制吗?
假设DMA连贯内存无法避免内存带宽问题,我已经研究了实现DMA传输到驻留在缓存RAM中的连续缓冲区的其他方法。
应该注意,对于图像分析性能来说,内存映像由CPU缓存支持是绝对必要的。即如果没有缓存支持,那么扩展DMA连贯缓冲区以容纳所有50个内存中映像并在该缓冲区中就地执行分析是不可行的解决方案。
我的下一个想法是(以某种方式)在缓存支持的内存中获取连续的缓冲区并使用流式DMA API。据我所知,流式DMA API完全符合我的要求,即转移'所有权'设备和CPU之间的内存缓冲区。我希望当缓冲区的所有权从设备传输到CPU时,API有效地用于使DMA缓冲区的缓存行无效。
任何人都可以确认这种理解是否正确吗?
如果是,那么我基本上需要的是一种在普通缓存支持的内存中获取连续缓冲区的方法。
一个明显的想法是在启动时保留内存(通过指定' boot&boot;参数)并使用mmap()将其映射到用户空间。但是我对这个主题的搜索表明内存带宽(缓存?)问题与这种类型的内存相同,与DMA相干内存相同。
任何人都可以确认(甚至更好地反驳)内存带宽对于保留的mmap内存有限,就像DMA相干内存一样吗?
另一个想法是使用Linux' CMA(连续内存分配器)API,看起来很有前途(见https://lwn.net/Articles/396707/)。但是CMA需要3.18内核,不幸的是我的系统只有3.14内核。
在启动时分配连续内存可能是另一个想法。但我的驱动程序是作为一个模块构建的,模块在启动时无法分配连续的内存......
这让我没有明显的解决方案。头疼...... 您是否有经验丰富的设备驱动程序开发人员能够让我了解如何尽可能有效地将图像传输到内存中?
/拉斯