mmap()在内存小时的性能

duanbeibei 2007-09-01 11:49:20
本人做流媒体开发的,工作中需要将mpg文件转化成一定格式发送到网络,由于文件太大,程序用mmap()来实现文件的读取,但在实测过程中发现一个大问题,如下:

服务器配置:
CPU:两颗至强3.0
内存:2G
磁盘:3个SATA硬盘组成磁盘阵列

测试时同时运行30个播放程序读取30个不同的mpg文件,程序起初运行画面播放非常流畅,几分钟过后,内存剩下15MB左右时,mmap()就开始不停的进行页面置换,将新的数据读入内存,老的数据置换出去,这时的磁盘利用率不到1%,但CPU耗在iowait上的时间却有90%多

各位大侠我该怎么办,如果不用内存映射还有没有其他的办法处理大文件???
...全文
524 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
hefuhua 2007-09-07
  • 打赏
  • 举报
回复
哈哈,
是件让人快乐的事,内核真的有点深
谢谢分享:)
别客气,我只是个初学者,一起继续努力!周末快乐!
duanbeibei 2007-09-07
  • 打赏
  • 举报
回复
问题已解决,好高兴^_^

问题原因:
调用mmap()时内核只是建立了逻辑地址到物理地址的映射表,并没有映射任何数据到内存。
在你要访问数据时内核会检查数据所在分页是否在内存,如果不在,则发出一次缺页中断,linux默认分页为4K,可以想象读一个将近2G的电影文件要发生多少次中断,I can't bear it!!!

解决办法:
将madvise()和mmap()搭配起来使用,在使用数据前告诉内核这一段数据我要用,将其一次读入内存,现在程序可以并发150个数据流了,每秒最高可读70MB数据


感谢大家的支持,另外还要特别感谢老兵哥在“timer frequency”问题上的支持,那个问题还有待研究,周末了,祝大家愉快。
hefuhua 2007-09-05
  • 打赏
  • 举报
回复
换个思维不用mmap()
redex 2007-09-05
  • 打赏
  • 举报
回复
或者DMA设置的参数太低
redex 2007-09-05
  • 打赏
  • 举报
回复
是不是DMA没打开??
duanbeibei 2007-09-05
  • 打赏
  • 举报
回复
SATA硬盘默认就是开启DMA得吧,内核里没有找到配置选项,用hdparm -d /dev/sdb也会失败
redex 2007-09-04
  • 打赏
  • 举报
回复
"今天又做了一下测试,先映射整个文件,在使用过程中一段一段释放 ... ..."

楼猪, 大家说的是先一次映射2M,在快读完时再映射下一段... 和你做的不一样啊,
时间多再试试吧, 和你共同关注.
duanbeibei 2007-09-04
  • 打赏
  • 举报
回复
今天重编了内核,有一项数据提升了,每秒读数据从7MB生到了8MB(用hdparm测得的磁盘输出率为150MB/sec,还差得远),IOWait问题依旧,这是今天测试的数据:
//----------------------------------------------------------------------------------------
Time: 03:32:10 PM
avg-cpu: %user %nice %system %iowait %idle
4.30 0.00 3.40 92.30 0.00

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sdb 34.20 0.00 133.00 0.00 16395.20 0.00 8197.60 0.00 123.27 24.90 186.88 7.52 100.04

Time: 03:32:20 PM
avg-cpu: %user %nice %system %iowait %idle
4.65 0.00 3.10 92.25 0.00

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sdb 29.70 0.00 132.40 0.00 16587.20 0.00 8293.60 0.00 125.28 24.51 185.28 7.56 100.03
//---------------------------------------------------------------------------------------------
只是想不明白CPU读磁盘就读磁盘呗,读不到数据可以进入休眠状态啊,干吗要忙等待
继续努力
hefuhua 2007-09-03
  • 打赏
  • 举报
回复
最好下2.6.23以下的内核,因为2.6.23把进程调度全改了,我觉得会有很多bug
duanbeibei 2007-09-03
  • 打赏
  • 举报
回复
今天又做了一下测试,先映射整个文件,在使用过程中一段一段释放,还是阻塞在IOWait,另外挂载4G交换分区的方法也试了,效果更差
在国外论坛上看了些IOWait的东东,有很多都说红帽企业版+Xeons处理器+磁盘阵列容易发生IOWait,和我现在的配置一模一样,用单独的大文件拷贝就能测得出来,明天下个新内核编译一下试试看
cceczjxy 2007-09-03
  • 打赏
  • 举报
回复
你可以分段映射试试看,比如一次映射2M,并跟踪程序在这个映射内的使用情况,如果这此映射的数据快用完时,就提前映射下一段.在上一段用完后,就释放掉其映射.
redex 2007-09-03
  • 打赏
  • 举报
回复
mark.
hefuhua 2007-09-02
  • 打赏
  • 举报
回复
开个4G的swap分区挂上去试试看
或者,把文件分段mmap(),如100M的文件做10次mmap(),并且要求在播放1段完前做好下段准备工作
jhs1982419 2007-09-02
  • 打赏
  • 举报
回复
必须得先压缩
dai_weitao 2007-09-02
  • 打赏
  • 举报
回复
你挂mmap不释放怎么行.
你mmap一个大文件, 要在这个大文件播放完后才能释放.
要把大文件分小

23,115

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧