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 速度慢。