使DMA内存暂时可缓存

时间:2013-06-10 17:18:11

标签: c linux caching mmap dma

我有一个arm cortex-a9四核设备,我正在编写一个多进程应用程序。 这些进程共享相同的输入源 - 一个DMA缓冲区,它们都使用mmap()调用进行访问。

我注意到进程访问DMA内存所花费的时间明显长于将输入源更改为普通分配缓冲区(即使用malloc分配)所花费的时间。

我理解为什么DMA缓冲区必须是不可缓存的,因为我能够确定缓冲区何时稳定(硬件不变,大多数情况下是这种情况)或脏(数据已更改)我认为如果我将内存区域暂时缓存,我可能会获得显着的速度提升。

有办法吗?

我目前正在使用此行来映射内存:

void *buf = mmap(0, size, PROT_READ | PROT_WRITE,MAP_SHARED, fd, phy_addr);

谢谢!

1 个答案:

答案 0 :(得分:1)

大多数现代CPU使用监听来确定是否/何时必须将缓存行刷新到内存或标记为无效。在这样的CPU上,“DMA缓冲区”与kmalloc()缓冲区相同。当然,这假设窥探功能正常工作,并且操作系统利用了窥探功能。如果你看到访问DMA和非DMA内存区域的差异,那么我只能假设你的CPU没有缓存侦听功能(检查CPU文档)或者没有使用该功能,因为它不起作用(检查CPU勘误表) )。

您提出的方法存在问题:

  1. 您知道何时将内存区域更改回不可缓存的内容吗?
  2. 更改内存区域的MMU设置并不总是微不足道的(取决于CPU),我不确定您的操作系统中是否存在用于更改此类设置的API。
  3. 即使有可能更改内存区域的MMU设置也存在风险,并且必须小心地将此类更改与DMA操作同步,否则几乎可以保证数据损坏。
  4. 鉴于所有这些重大问题,我建议更好的方法是在检测到DMA缓冲区更新时将数据从DMA缓冲区复制到kmalloc()缓冲区。