免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: obrire

快速内存操作技术 [复制链接]

论坛徽章:
0
发表于 2006-04-14 12:14 |显示全部楼层
当前的LKM中,Linux内核是尽可以地使用你的物理内存,以便系统响应快速
但有一个致命的缺限,如果你在启用X-Windows以及一系统大型应用时
从free看出你的物理内存已经很少了,这时采用LKM动态加载内存需求较大的内核模块时
不一定能成功,这非常要命,当不能得到页面时,__get_free_pages会触发VMA将
快速交换,此时大块物理内存被释放,但系统本身却一直与外存持续交换,系统响应变得
很慢,物别是在GUI模式下。即便如此,你再加载LKM时,还是不能成功,这是不可以理解的。

已经有不少朋友在mlist中提出,这必须得将VMA进行修正。

有时,我在init 3/init 1下工作正常,而init 5时,动态加载几乎不成功。
这对于开发而言,是不可思议的

论坛徽章:
0
发表于 2006-04-14 12:19 |显示全部楼层
sysenter这种实现我早就知道了,这时一个几年前的东西了, 我也知道他的效率很高.
其实直接操作/dev/mem的事情我很早就用过, 但是对于实际开发来说.

更改所有用户空间的内存管理方法, 直接操作物理内存,  你怎么保证系统库能正常运行?  如果你不需要系统库, 你编写上层应用程序, 是否要替换所有内存操作代码? 对于分配的所有物理页,你是否要自己管理他的碎片, 等问题? 你是否考虑到了这样的改动对于所有的上层应用程序来说, 有多少附加的工作量?

为什么我用mlock, 只是说把mlock可以用来在用户和内核之间通信使用. 请问,你一次有多少数据量要在用户和内核之间交互?   我现在的使用中都是足够的. 而这种方法的改动是最小的, 效率也不比你提到的低.

对于用户空间任务之间的数据交互, 用线程可以减少很多麻烦.

论坛徽章:
0
发表于 2006-04-14 12:30 |显示全部楼层
to obrire,

我看了你的做法,觉得不错。
比如,在用户空间malloc()了32M虚拟地址,如何在用户空间知道其物理开始地址并且打开/dev/mem线性操作相应的地址?

论坛徽章:
0
发表于 2006-04-14 12:30 |显示全部楼层
另外, 你多次提到有人建议linus修改vma和mm的实现, 能否给出讨论的链接地址, 多谢!

论坛徽章:
0
发表于 2006-04-14 12:53 |显示全部楼层
to orbire

是不是这样:

m = open("/dev/mem", ...);
lseek(m, 1204, 0);
read(m, buf, sizeof(buf));
write(m, "123456", 6);

直接操作物理内存?


"
在内核空间申请
在用户空间不用mmap
直接open /dev/mem
lseek xxxxx
一切就哪样简单,就像汇编,写进去就行了.
这可是直接物理内存操作呀.
其实在性能要求高的环境,不需要外存的.有些Super Computer就是这样的.
结果直接就通过网络送走了.
"

论坛徽章:
0
发表于 2006-04-14 16:29 |显示全部楼层
原帖由 思一克 于 2006-4-14 12:53 发表
to orbire

是不是这样:

m = open("/dev/mem", ...);
lseek(m, 1204, 0);
read(m, buf, sizeof(buf));
write(m, "123456", 6);

直接操作物理内存?


"
在内核空间申请 ...

正是,当你得先知道确切的物理地址, 也就是OFF_SET,一般我的系统分配在0x600000以后.
我采用在/proc/mem_window输出一个地址及尺寸, 然就这样操作了

论坛徽章:
0
发表于 2006-04-14 16:41 |显示全部楼层
to orbire,

那你了解read write /dev/mem还要调用copy_fro_user, copy_to_user?

/dev/mem仅仅是一个影射物理内存的字符设备,读写它要通过文件系统的许多调用,最后才调用read_mem, 和write_mem, 然后就是copy_from/to_user,怎么能比mmap快?


原帖由 obrire 于 2006-4-14 16:29 发表

正是,当你得先知道确切的物理地址, 也就是OFF_SET,一般我的系统分配在0x600000以后.
我采用在/proc/mem_window输出一个地址及尺寸, 然就这样操作了

论坛徽章:
0
发表于 2006-04-14 16:51 |显示全部楼层
原帖由 思一克 于 2006-4-14 12:30 发表
to obrire,

我看了你的做法,觉得不错。
比如,在用户空间malloc()了32M虚拟地址,如何在用户空间知道其物理开始地址并且打开/dev/mem线性操作相应的地址?

首先,你要得到用户空间地址在内核空间的入口, 用逻辑地址并减去PAGE_OFFSET才能得到物理地址.
与高端内存的关系,你要看看你当前版本的源定义,不一而足

如果纯粹在用户空间用malloc, 并不能保证你能得到性线物理地址.

因此才有我说的,先在内核模块中规划, 然后在用户空间自由使用

所以在用户空间用malloc是无法保证性能和线性的.在VMA中可以保证你看起来是线性的.
但内核实现, 完全可以采用relayfs(2.6.14以后加入)方式,用多组不同大小的页面组来完成映射(list),
只是你在用户空间感觉不到.

如果你想这样使用, 建议你也先在内核空间划出一块来, 然后在用户空间操作.

我是因为我的PCI总线的上设备要求在相关Register置入物理地址, 并要求在块线性空间,才不得不这样呀.
主要是方便DMA传送. 如果全在内核模块中做,有些功能不方便,不如用户空间编程方便,所以行此法.

只是这方面你的代码千万不能越界,如果打开/dev/mem以后,在其它区间写入了数据,
会让系统变得不可思议了.

我所讲的无非三点
1. 方便在用户空间直接操作物理内存
2. 线性读写/块传输
3. 内核模块中实现了DMA传输完成IRQ响应,用户程序完全可以while(1)直接操作
使得编程接口简单高效, 就像实时preview高速视频一样.其它线程编码不受影响
至于同步问题, 用什么机制, 尊重你自己的选择,别让work_queue锁死了.如果有硬时钟就好了
应用层可以多路POOLING,内核层采用中断

论坛徽章:
0
发表于 2006-04-14 16:52 |显示全部楼层

回复 27楼 思一克 的帖子

当然不会了,就是不用copy_to_user这类函数了
要写什么你直接置入就可以

只是这种管理状态,如有些区域设置同步位,要求自己要有较高的编程管理能力
混合模型: 每次同记录在/proc/mem_window中,锁一打开,应用就读写或刷新.
这不影响系统其它应用,全在你自己的空间,或者同步块标志在这片物理区更好,性能
上更有效一些.

[ 本帖最后由 obrire 于 2006-4-14 16:56 编辑 ]

论坛徽章:
0
发表于 2006-04-14 16:55 |显示全部楼层
to obrire,

内核中自己的VMA的物理地址是连续的吗?


"所以在用户空间用malloc是无法保证性能和线性的.在VMA中可以保证你看起来是线性的.
但内核实现, 完全可以采用relayfs(2.6.14以后加入)方式,用多组不同大小的页面组来完成映射(list),
只是你在用户空间感觉不到.
"
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP