malloc 与 mmap 内存读写效率问题
记录由于 cache 导致的 malloc 和 mmap 读写速率差异,原文地址
问题
现在在一个嵌入式平台上遇到内存读写效率问题:
应用层分出 2 类内存:一种是 malloc 分配出来的,
第二种通过内核 ioremap 一块内存,再将这块内存 mmap 给应用。
(这块内存在内核管理范围之外,即 DDR 总共 128MB,内核参数指定 mem=64MB, ioremap 出后 64MB,然后 mmap 给应用)
应用层测试发现,
malloc出的内存之间读写速度可以达到 170MBps,malloc内存与mmap内存之间的读写速度只有 40MBps 左右,mmap内存与mmap内存之间的读写速度更低些大约只有 30MBps。
而内核下测试,ioremap 出的内存与 vmalloc/kmalloc 出的内存之间的读写速度,基本保持一致。
怀疑这种差异跟 mmap 有关,但是又不太熟悉内核内存管理这块,不太清楚 malloc 出的内存与 mmap 出的内存之间的本质区别,所以向各位请教下,这 2 种不同方式分配出的内存为什么读写效率上存在如此大的差异?
解决
- 在
kernel里使用ioremap分配出来的一段memory不经过cache(或者说对这一段 memory 的读写都会直接操作 memory)并且物理地址是连续的,而user space里使用malloc分配出来的memory则没有以上保证,我看不出来在MMU enable的情况下物理地址是否连续对memory的读写效率有什么影响,所以问题应该在是否经过cache这里,我也不是很确定。 - 感觉不是
ioremap的问题,因为我用get_free_pages申请内核管理的一段连续内存再mmap给应用,情况也是一样。 我尝试在驱动的mmap函数中将vma->vm_page_prot由pgprot_noncached修改为pgprot_writecombine。读取mmap内存到malloc内存的速度几乎无变化,但写malloac内存到mmap内存的速度有近乎 2 倍提升。 nocached和writecombine应该都是bypass。cache系统的,nocached是对每个byte操作都发起一个内存请求,而writecombine是能合并多个内存请求为一个,从而减少内存请求的数量。- 使用默认的
vm_page_prot(使用cache和writebuffer),mmap和malloc内存的速度测试可以一致。 之前使用nocache的原因是共享出的内存需要与另外一个异构核通信,为了避免cache引发通信出错而设置的。现在可以想办法区分这两种情况。
其它问题
播放网络视频频繁缓冲,最后结论:
usb 转网口拷贝时 DMA 使用的地址带 cache,而网卡直连时 DMA 使用的地址不带 cache,所以网卡直连时 memcpy 速度慢。