免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 14908 | 回复: 55
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-12 11:55 |只看该作者 |倒序浏览
我们总希望能在内核空间和用户空间自由交换数据,传统的方式是采用内核提供的vma机制,通过copy_to/from_user之类的方法来实现。这对于高速数据块传送是不可取的。
其实kswapd有时交换数据至外存时,性能相当差,一般而言,你的PC主存并不见得就用尽了,而且很多应用并是你所关心的,但却实实在在消耗你的计算资源,此时,你可能会想到采用实地址操作你的应用(尽管有MMU的支持),在uClinux中,当没有MMU时,工作起来是挺爽的。
最方便的,最高效的,无非是实地址下,操作物理内存,相当于DMA。尽管Linux 2.6内核在VMA方面的性能要优于2.4,但swap机制有一定的缺限。在VxWorks中,对内存的管理是很细致且精确的。如果你在Linux下申请大块内存操作时,当触发kswap快速交换回主存时,你会发现你的计算机
哪一段时间,几乎要休息几分钟,尽管你看起来free输出的頁面已经很多了,但此时的外存几乎一直忙着,且CPU负荷相当重,这时也可能你根本就没做任何操作。
有没有办法既在VMA机制下工作,又能直接处理主存数据呢?
回答是肯定的:
内核启动后,会将主存映射为/dev/mem,当我们在VMA中申请一块逻辑区间后,将转换的物理地址传与用户空间,用户空间就可以线性操作这段区间了,直接采用mmap就可以在物理主存中读写。
还有更快的方式吗?不采用mmap行吗?
当然有,当VMA将物理区块地址及大小传与用户空间后,用户完全可以采用地址读写模式,这几近于机器指令操作了。(可以独立于OS之外)
此种实现方式很简单,首先打开/dev/mem,直接定位至VMA传上来的地址就可以操作了,无需mmap。通知用户空间,可以采用procfs/sysfs等。
强烈建议:在边界控制上,一定要精确细致,不推荐初学者采用,一旦越界,可能引起“Kernel Panic”
更有可能就DOWN了。
对于此实现方式,建议参考mapper(LDD3)程序。
同时,也可以用mapper检查读写是否正确。

新的IA32中,PAGE_SIZE = 4K
            MAX_ORDER = 11
gfp最大申请4M线性逻辑空间,减去PAGE_OFFSET即可得到物理地址。
如果采用了HIMEM和NUMA,请参见Kernel关于内存映射的算法。
当主存达到1G或超过时,请减小用户空间大小。
随着硬件技术的发展,VMA在主存相当大时,可以考虑进行修正,完全可以集中采用物理映射方式。没必要交换了。否则,反而影响性能。
32位平台,如果主存2G,采用SWAP会使得性能有较大下降。
而在大容量数据传输时,也不可能采用SWAP方式的,不允许换出。
建议Linus在VMA中加入进程分类,不平类别的应用,分配不同的内存块。
小数据PAGE_SIZE = 4K/大数据4M/128M
地址模式全转换为64位,兼容32位,当应用于Embedded系统时,直接使用32位模式。
如将做成多个微系统,不同微核,运行不同应用(不同的进程管理,内存管理,文件管理),只是接口可以统一,不同标志而已。

论坛徽章:
0
2 [报告]
发表于 2006-04-12 12:36 |只看该作者
非常好!

论坛徽章:
0
3 [报告]
发表于 2006-04-13 09:40 |只看该作者
个人觉得,根本不可行!

首先, 你提到的在vma存在的情况下, swap存在的情况下, 直接访问物理内存. 而且,看情况这块物理内存是用户空间分配的.
在mmu的CPU中, page frame映射到 page中, 不是固定的, 更确切的说, 一块物理页, 如果是用户空间分配的, 不是只给一个任务使用的, 因为swap处于运行中.  别以为你直接访问物理内存, swap就不运行了, 你要用内核的分配物理页函数, 就可能触发kswap

直接访问page frame, 可能导致访问到的page frame存放的是已经被切换出去的任务的数据. 即使你非常注意访问的准确性.

再者,  你这里说得所有东西都没考虑到, 用户任务分配好vma后, 物理地址根本是不确定的. 要不内核的lazy map机制就没用了.

最后, 内核现在的实现已经有非常好的扩展性, 可能是你了解不多. 根本不需要你说得这么多复杂的东西.
在嵌入式mmu CPU环境下,通过 mlock + 锁的技术,可以在内核和用户空间直接在有限的物理页上交换数据. 用户空间malloc几页物理内存, 然后在每页中写入一两个字符, 以完成内核的page frame 到page的映射, 然后用mlock()锁定这几页, 不然swap运行. 然后就可以用这几页来完成用户空间和内核的数据交互. 不过锁的实现都要考虑.

还有, 嵌入式环境没有磁盘, 一般需要将swap off, 就是设置内核的watermark level为0,这样kswap就不会将物理页交换. 直接调swapoff命令. 或者写/proc/sys/vm/swappiness

内核对vm分配也有限制, 所以用户空间malloc过大的空间,也可能不成功, 这时内核的 over commit功能.

论坛徽章:
0
4 [报告]
发表于 2006-04-13 09:55 |只看该作者
原帖由 xiaozhaoz 于 2006-4-13 09:40 发表
个人觉得,根本不可行!

首先, 你提到的在vma存在的情况下, swap存在的情况下, 直接访问物理内存. 而且,看情况这块物理内存是用户空间分配的.
在mmu的CPU中, page frame映射到 page中, 不是固定的, 更确切的说, ...


正看的过瘾呢, 是不是还没打完字呀?

论坛徽章:
0
5 [报告]
发表于 2006-04-13 10:37 |只看该作者
原帖由 albcamus 于 2006-4-13 09:55 发表


正看的过瘾呢, 是不是还没打完字呀?


没了, 就这些东西, 对内存这块不怎么懂, 不敢乱说.

不过将vm分成 3G/IG, 2G/2G, 1G/3G的选项已经合入最新的内核2.6.17-RC1, 正在看实现.

讨论在:
http://groups.google.com/group/l ... =2#f99732a73435db13

论坛徽章:
0
6 [报告]
发表于 2006-04-13 11:15 |只看该作者
争论的很激烈吗

论坛徽章:
0
7 [报告]
发表于 2006-04-13 23:07 |只看该作者

回复 5楼 xiaozhaoz 的帖子

首先,在普通的PAGE_SIZE情况下,如4K不是4M,能得到的order最大为11,其实一般是<11
也就是取10,源码中有定义,只能用到4M Logical Memory,也就是只能得到4M线性物理地址.
而在uClinux中,虽然没有kswapd,但当你的应用free或destroy时,内核并不能如你所想,全
然释放.
至于上有人提到内存分配问题,这是在Module中分配的.不会有在初始化时加入mem=xxM的限制
这些内存在module unload时,可以回归内核管理.
至于用户空间所采用的malloc,其实只是让内核知道这段内存的申请是合法的,最后还是通过page
来实现的.
当然,如果纯64位平台,可以采用4M的PAGE_SIZE
如果定义MAX_ORDER <= 1024, 可以使用4G的Memory.
以前有Intel的朋友试着做过这些分配,或有人在2.6.14以后加入relayfs,其实这都不可能保证性线.

如果我们采用Multi Micro Kernel, 就有点像IBM的虚拟机了,可以同时运行多种OS,多种管理模式,
不过管理调度是相当复杂的, AIX中有加入对SMP和多种微环境支持.

VMware中有一定的实现功能, 性能也还可以,但在要求苛刻的应用下,如同步数传系统中,当前的内核
就不足以应对了. 2.6的VMA制式,在通常用户计算环境中,性能是出色,好像在2004年Moto中有人做
个这种测试,有机会传上来看看.

如果有两枚,或非SMP(3-5枚)CPU,有可能我要求一段内存完成100M的线性DMA转发数据,<1ms的
时延,这时可安排其中一枚来做这件事,这是可行的,有时更不需要1ms,只是数据后处理要求时间稍长.

非对称模式,或称混合网络计算模式,单主机也可以实现. 以前有些SuperComputer采用背板高速串行
数据交换,可以有首效隔离,采用BLADE单元计算,但这不能共享非空时段内的Memory资源.

如果没有负荷时,有些内存需要为主运算平台的诸如DB/WWW服务,可以通过一些机制来完成动态remap.

大家有兴趣研究一下SMP/及非对称多CPU共存计算环境.

CELL将很多核做进一个Chip, 但不如通过其它IO总线,扩展多路CPU,既可以每路CPU自带MEMORY和CACHE,
也可以动态向主OS动态申请,且加入是动态的,不需要主OS环境停机.

是不是很爽呀, 你突然发现图形处理不过来了,接上USB外置处理器,负荷转移置专用CPU上,一下快多了
不用时,unload就好了.主存自动回归原计算环境.真是CBL.

社会本就多态, 有什么花样, 就突破限制.
F.E.U
Future Extension Union

[ 本帖最后由 obrire 于 2006-4-13 23:24 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2006-04-13 23:29 |只看该作者
原帖由 xiaozhaoz 于 2006-4-13 09:40 发表
个人觉得,根本不可行!

首先, 你提到的在vma存在的情况下, swap存在的情况下, 直接访问物理内存. 而且,看情况这块物理内存是用户空间分配的.
在mmu的CPU中, page frame映射到 page中, 不是固定的, 更确切的说, ...

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

论坛徽章:
0
9 [报告]
发表于 2006-04-13 23:39 |只看该作者

回复 3楼 xiaozhaoz 的帖子

即便是MVista提供的核心中,也不见得保证VMA工作得很好.
内存一大,释放就可能变得很有效.当我用MPlayer static版时,退出时,好像内存并未很快释放.
如果还像MV采用spin_lock,就不用我写这部分了.在block操作时,只有memcpy,memset.

DMA操作时,如果映射都是10M以上的,怎么办?如果有硬时钟要求,每秒要提取序列,怎么实现???
目前有哪家的Linux能达到VMA全速实时?电信用户可不像IA产品.

即便是100Mbps的网卡,也不像10M同步信号要求那么高.

严重声明:
      采用这种方式, 是不需要在用户空间用malloc的(没有任何加锁时延及浪费),完全就是Register
     操作方式,直接置数.
    一般在procfs中读取时,如你用了系统的task_lock,这对要求不高的应用是可行的.
     至于在IA32中采用2G/2G/1G/3G,目前内核都没有问题.
     
当大容量内存在内核空间申请时,启用VMA,有时不见得成功,反而会触发系统自动将外存的数据换回主存.
这时系统几乎很少响应其它应用,且长时间调整(特别是换回在100M以上时).

至于细节,不便公开,望诸位见谅.以上只说明实现方式,是可行的.
有人问过Linus,但他只提及采用其它方式,或将用户空间缩小.所以我建议他们两个主创修改这部分实现.
反正他们自己也在争论.

尊重他们,体系可以不变,但可以变通的是方法.

如果大家对嵌入式哪么了解, 我可以推荐.

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

论坛徽章:
0
10 [报告]
发表于 2006-04-14 00:32 |只看该作者
支持!

linux还是有很多可以改进德地方德,以前也遇到需要分配大于4M空间德情况,郁闷!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP