1.Ariane处理器源码剖析(五)续:MMU
2.MappedByteBuffer VS FileChannel å°å¼ºå°å¼±ï¼
3.linux内核$(kallsyms.o)详解续篇 --- 内核符号表的生成和查找过程
4.uclinux缺点
Ariane处理器源码剖析(五)续:MMU
虚拟存储器概念
在没有使用虚拟地址的系统中,处理器输出的地址直接送到物理存储器。而使用虚拟地址时,处理器输出的地址为虚拟地址,不会直接送到物理存储器,需要先进行地址转换。会员分销源码下载负责转换的部件称为MMU。
使用虚拟存储器不仅可以减少物理存储器容量需求,还有保护和共享等好处。虚拟地址通过页表(PT)映射到物理地址。页表存储虚拟地址到物理地址(***到PFN)的对应关系,表格大小取决于系统可用内存。页表结构不同于Cache,直接使用***寻址,无需Tag。
访问虚拟地址时,可能需要两次物理内存访问:先访问页表获取物理地址,王者背景替换源码再使用物理地址访问内存。现实中,处理器使用TLB和Cache加速过程。多级页表减少页表占用空间,TLB负责快速查找。缺页(Page Fault)发生时,从下级存储取页并更新页表。
操作系统使用页表控制每个页的访问权限,实现程序权限管理。写通(Write Through)方式在某些Cache间使用,写回(Write Back)类型Cache中,指令执行时仅更新D-Cache,物理内存更新可能延迟。
TLB(Translation Lookaside Buffer)作为页表缓存,提高访问速度。现代处理器采用两级TLB,车型源码是什么容量和替换策略影响性能。TLB缺失可能由软件或硬件触发,随机替换算法适用于TLB。TLB写入确保页不被替换。控制TLB和Cache需管理进程ID等信息。
虚拟Cache通过虚拟地址寻址,与物理Cache不同,仍需TLB加速访问。虚拟Cache引入同义和同名问题,通过进程ID解决。控制Cache包括写操作、寻址策略等。将TLB和Cache放入流水线优化性能,限制了Cache大小。使用Virtually-Indexed, Virtually-Tagged方式,虚拟Cache与物理Cache结合解决重名问题。码上溯源码
MMU模块、TLB、虚拟内存系统、PTW等组件实现虚拟存储器功能。通过不同策略优化访问速度和内存使用。
MappedByteBuffer VS FileChannel å°å¼ºå°å¼±ï¼
Java å¨ JDK 1.4 å¼å ¥äº ByteBuffer ç NIO ç¸å ³çç±»ï¼ä½¿å¾ Java ç¨åºåå¯ä»¥æå¼åºäº Stream ï¼ä»è使ç¨åºäº Block çæ¹å¼è¯»åæ件ï¼å¦å¤ï¼JDK è¿å¼å ¥äº IO æ§è½ä¼åä¹çââ é¶æ·è´ sendFile å mmapãä½ä»ä»¬çæ§è½ç©¶ç«æä¹æ ·ï¼ å RandomAccessFile æ¯èµ·æ¥ï¼å¿«å¤å°ï¼ ä»ä¹æ åµä¸å¿«ï¼å°åºæ¯ FileChannel å¿«è¿æ¯ MappedByteBuffer å¿«......(é¶æ·è´åè Zero Copy I: User-Mode Perspective )
天åï¼é®é¢å¤ªå¤äºï¼ï¼ï¼ï¼ï¼ï¼
让æä»¬æ ¢æ ¢åæã
æ们ç¥éï¼Java ä¸çæå¾å¤ MQï¼ActiveMQï¼kafkaï¼RocketMQï¼å»åªå¿ MQï¼èä»ä»¬åæ¯ Java ä¸çä½¿ç¨ NIO é¶æ·è´ç大æ·ã
ç¶èï¼ä»ä»¬çæ§è½å´å¤§ç¸åï¼æå¼å ¶ä»çå ç´ ï¼ä¾å¦ç½ç»ä¼ è¾æ¹å¼ï¼æ°æ®ç»æ设计ï¼æ件åå¨æ¹å¼ï¼æä»¬ä» ä» è®¨è®º Broker 端对æ件ç读åï¼ççä»ä»¬æä»ä¹ä¸åã
ä¸å¾æ¯æ¥¼ä¸»æ¥çæºç æ»ç»çå个 MQ 使ç¨çæ件读åæ¹å¼ã
é£ä¹ï¼å°åºæ¯ MMAP 强ï¼è¿æ¯ FileChannel 强ï¼
MMAP ä¼æå¨ç¥ï¼åºäº OS ç mmap çå åæ å°ææ¯ï¼éè¿ MMU æ å°æ件ï¼ä½¿éæºè¯»åæ件å读åå åç¸ä¼¼çé度ã
é£ FileChannel å¢ï¼æ¯é¶æ·è´åï¼å¾éæ¾ï¼ä¸æ¯ãFileChannel å¿«ï¼åªæ¯å 为ä»æ¯åºäº block çã
æ¥ä¸æ¥ï¼benchmark everything ââ å¾å¦.
å¦ä½ Benchmarkï¼ Benchmark åªäºï¼
æ¢ç¶æ¯è¯»åæ件ï¼èªç¶å°±è¦ç读åæ§è½ï¼è¿æ¯æåºæ¬çãä½ï¼æ³¨æï¼é常 MQ ä¼ä½¿ç¨å®æ¶å·çï¼é²æ¢æ°æ®ä¸¢å¤±ï¼MMAP å FileChannel é½æ force æ¹æ³ï¼ç¨äºå° pageCache çæ°æ®å·å°ç¡¬çä¸ãforce ä¼å½±åæ§è½åï¼ çæ¡æ¯ä¼ãå½±åå°ä»ä¹ç¨åº¦å¢ï¼ ä¸ç¥éãæ¯æ¬¡åå ¥çæ°æ®å¤§å°ä¼å½±åæ§è½åï¼æ¯«æ çé®ä¼ï¼ä½è§åæ¯ä»ä¹å¢ï¼FileOutputStream ççä¸æ æ¯å¤åï¼çæ¡æ¯ä¸ä¸å®ã
ä¸ç´ä»¥æ¥ï¼æ件è°ä¼é½æ¯èºæ¯ï¼å 为影åæ§è½çå ç´ å¤ªå¤ï¼é¦å ï¼SSD çåºç°ï¼å·²ç»è®©ä¼ ç»åºäº B+ tree çæ å½¢ç»æ产çäºèªæçé®ï¼ç¬¬äºï¼æ¯ä¸ªæ件系ç»çæ§è½ä¸åï¼Linux ext3 å ext4 æ§è½å¤©å£¤ä¹å«ï¼å é¤æ件çæ§è½å·®è·å¨ åå·¦å³ï¼ãè Max OS ç HFS+ ç³»ç»è¢« Linus 称ä¹ä¸ºâæå²ä»¥æ¥æåå¾çæ件系ç»âï¼å¹¸è¿çæ¯ï¼è¹æç»äºå¨ å¹´æ¨éäº macOS High Sierra å iOS .3 ç³»ç»ï¼è¿ä¸ªä¸¤ä¸ªç³»ç»é½æå¼äº HFS+ï¼æ¢æäºæ§è½æ´é«ç APFSãèæ¯ä¸ªæ件系ç»åå¯ä»¥è®¾ç½®ä¸åçè°åº¦ç®æ³ï¼å¦å¤ï¼è¿æèæå å缺页ä¸æ带æ¥çæ§è½æ¯åº.......
ï¼tipsï¼è¯å¿ç RocketMQ æä¾äº Linux IO è°ä¼çèæ¬ï¼è¿ç¹åçä¸é ï¼ï¼
è·é¢äºã
楼主åäºä¸ä¸ªå°é¡¹ç®ï¼ç¨äºæµè¯ Java MappedByteBuffer & FileChannel & RandomAccessFile & FileXXXputStream ç读åæ§è½ã大家ä¹å¯ä»¥å¨èªå·±çæºå¨ä¸è·è·çã
CPUï¼intel i7 4æ ¸8çº¿ç¨ 4.2GHz
å åï¼GB DDR4
ç£çï¼SSD 读å 2GB/s å·¦å³
JDK1.8
OSï¼Mac OS ..6
èæå åï¼ æªå ³éï¼å¤§å° 9GB
æµè¯æ³¨æç¹ï¼
1GB æ件ï¼
æµè¯ MappedByteBuffer & FileChannel & RandomAccessFile & FileInputStream.
ä»è¿å¼ å¾éï¼æ们çå°ï¼mmap æ§è½å®èï¼ç¹å«æ¯å¨å°æ°æ®éçæ åµä¸ãå ¶ä»çæµï¼åªæå¨4kb çæ åµä¸ï¼æå¼å§åæ mmapãå æ¤ï¼è¯» 4kb 以ä¸çæ°æ®ï¼è¯·ä½¿ç¨ mmapã
åæ¾å¤§çç mmap å FileChannel çæ¯è¾ï¼
æ ¹æ®ä¸å¾ï¼æ们çå°ï¼å¨åå ¥æ°æ®å å¤§äº 4kb 以ä¸çæ åµä¸ï¼FileChannel çä¸ä¼éé¶æ·è´ï¼åºæ¬å®è mmapï¼é¤äºé£ä¸ªä¸æ¬¡è¯» 1G æ件ç BT æµè¯ã
å æ¤ï¼å¦æä½ çæ°æ®å å¤§äº 4kbï¼è¯·ä½¿ç¨ FileChannelã
1GB æ件ï¼
æµè¯ MappedByteBuffer & FileChannel & RandomAccessFile & FileInputStream.
ä»ä¸å¾ï¼æ们å¯ä»¥çåºï¼mmap æ§è½è¿æ¯ä¸æ ·ç稳å®ãFileChannel ä¹ä¸å·®ï¼ä½æ¯å¨ åèæ°æ®éçæ åµä¸ï¼è¿å·®ç¹ææã
åç缩ç¥å¾ï¼
æ们çå°ï¼åè æ¯ FileChannel å mmap æ§è½çåæ°´å²ï¼ä» åèå¼å§ï¼FileChannel ä¸è·¯åæï¼ç´å° BT 1GB æ件ç¨ç¨è¾äºä¸ä¸¢ä¸¢ã
å æ¤ï¼æ们建议ï¼å¦æä½ çæ°æ®å 大å°å¨ åè以ä¸ï¼è¯·ä½¿ç¨ FileChannel åå ¥ã
æ们ç¥éï¼RocketMQ 使ç¨å¼æ¥å·çï¼é£ä¹å¼æ¥ force 对æ§è½æ没æå½±åå¢ï¼benchmark everythingãæ们使ç¨å¼æ¥çº¿ç¨ï¼æ¯ kb å·çä¸æ¬¡ï¼ççæ§è½å¦ä½ã
mmap ä¸ç´è½åï¼ä¸æ§è½å¾å·®ï¼é¤äºå¨ åèé£éæä¸ç¹ç¹æå¨ï¼åºæ¬ç»´æ å¨ å·¦å³ï¼è没æ force çæ åµä¸ï¼åå¨ å·¦å³ãè FileChannel åå®å ¨ä¸å force çå½±åãå¨æçæµè¯ä¸ï¼1GB çæ件ï¼ä¸æ¬¡ force éè¦ æ¯«ç§å·¦å³ãbuffer è¶å¤§ï¼æ¶é´è¶å¤ï¼åä¹åè¶å°ã
说个é¢å¤è¯ï¼Kafka ä¸ç´ä¸å»ºè®®ä½¿ç¨ forceï¼å¤§æ¦ä¹æè¿ä¸ªåå ãå½ç¶ï¼Kafka è¿æèªå·±çå¤å¯æ¬çç¥ä¿è¯æ°æ®å®å ¨ã
è¿éï¼æ们å¾åºç»è®ºï¼å¦æä½ éè¦ç»å¸¸æ§è¡ forceï¼å³ä½¿æ¯å¼æ¥çï¼ä¹è¯·ä¸å®ä¸è¦ä½¿ç¨ mmapï¼è¯·ä½¿ç¨ FileChannelã
åºäºä»¥ä¸æµè¯ï¼æ们å¾åºä¸å¼ å¾è¡¨ï¼
å设ï¼æ们çç³»ç»çæ°æ®å å¨ - å·¦å³ï¼æ们åºè¯¥ä½¿ç¨ä»ä¹çç¥ï¼
çï¼è¯»ä½¿ç¨ mmapï¼ä» ä» åä½¿ç¨ FileChannelã
ååè¿å¤´çç MQ çå®ç°è 们ï¼ä¼¼ä¹åªæ QMQ æ¯ è¿ä¹åçãå½ç¶ï¼RocketMQ ä¹æä¾äº FileChannel çåé项ãä½é»è®¤ mmap åå å¼æ¥å·çï¼åºè¯¥æ¯ broker busy çå å¶å§ã
è Kafkaï¼å 为é»è®¤ä¸ forceï¼ä¹æ¯ä½¿ç¨ FileChannel è¿è¡åå ¥çï¼ä¸ºä»ä¹ä½¿ç¨ FileChannel 读å¢ï¼å¤§æ¦æ¯å 为æ¶æ¯ç大å°å¨ 4kb 以ä¸å§ã
è¿æ ·ä¸æ£æµï¼è¿äº MQ ç设计似ä¹é½é常åçã
æåï¼è½ä¸ç¨ force å°±å«ç¨ forceãå¦æè¦ç¨ force ï¼å°±è¯·ä½¿ç¨ FileChannelã
linux内核$(kallsyms.o)详解续篇 --- 内核符号表的生成和查找过程
在内核中,维护着一张符号表,记录着内核中的所有符号,包括函数与全局变量的地址与名称。这张表嵌入在内核镜像中,供内核运行时随时查找符号名。通过调用__print_symbol,内核代码能打印出符号名。 接下来,我们将详细解析内核符号表的生成与查找过程。系统映像文件与/proc/kallsyms的安卓源码asop区别与联系
系统映像文件(System.map)在编译内核时生成,记录了内核中的所有符号及其在内存中的虚拟地址。文件由scripts/mksysmap脚本生成,依赖于nm命令。系统映像文件的每条记录包括地址、符号类型与符号名。符号类型包括函数、全局变量等。 而/proc/kallsyms文件是在内核启动后自动生成,位于/proc目录下,其代码实现于kernel/kallsyms.c。区别在于它包含了内核模块的符号列表,并且允许用户态访问,非内核常规操作。通常,我们只需关注_stext ~ _etext 和 _sinittext ~ _einittext之间的符号。内核符号表的生成与查找
内核在运行过程中可能需要查找地址对应的函数名,如Oops或调试信息输出。但内核并未依赖System.map或/proc/kallsyms文件,而是通过vmlinux中的符号表(.tmp_vmlinux2.o)实现快速查找。内核符号表结构
内嵌符号表通过scripts/kallsyms工具生成,源码位于kallsyms.c。该表包含6个全局变量:kallsyms_addresses、kallsyms_num_syms、kallsyms_names、kallsyms_token_table、kallsyms_token_index与kallsyms_markers。其中,kallsyms_addresses记录所有符号地址,kallsyms_num_syms统计符号数量,kallsyms_names存放符号名,kallsyms_token_table与kallsyms_token_index用于压缩存储高频率字符串。压缩算法与优化
内核使用压缩算法减少存储开销,将高频率字符串表示为token,并通过kallsyms_token_table与kallsyms_token_index实现压缩与解压。kallsyms_markers将符号每个分组,加速查找过程。查找过程实例与源码分析
举例说明查找地址0xc对应的符号名。首先在System.map中定位到该地址位于__create_page_tables与__enable_mmu之间。在.tmp_kallsyms2.S文件中,利用二分查找定位符号地址,然后通过kallsyms_names与kallsyms_markers加速查找过程。最后解析压缩的符号名,得到结果为__enable_mmu。内核模块符号查找
内核模块在启动时动态加载,其符号表存储在struct module结构中,所有已加载模块的struct module结构构成全局链表。查找内核模块中的符号时,调用kallsyms_lookup()函数,模块符号查找由get_ksymbol()函数完成。uclinux缺点
如同古训所述,“金无足赤,人无完人”,uClinux同样存在一些局限性: 首先,它的文档资源有待完善。相比Linux等开源项目,uClinux的文档体系显得组织混乱,缺乏系统性和一致性。热点技术的文档虽然丰富,但分类杂乱,而对于非热点部分,文档甚至可能存在真空状态,开发者往往需要深入源代码内部才能找到所需信息,这无疑增加了开发的难度。 其次,由于uClinux与硬件平台紧密关联,商业平台通常能享受到更快的代码更新和Bug修复,使得开发过程顺畅。然而,对于那些非商业支持的平台,其内核和应用代码的维护则相对滞后,这可能导致在编译时遇到问题,特别是当增加新应用或更新运行库时,经常会出现编译错误。这无疑增加了开发者的工作负担,可能导致开发进度的延误。 总之,尽管uClinux在嵌入式系统领域有着广泛应用,但其文档和硬件平台支持的差异性问题,无疑对开发者提出了更高的技术要求和挑战。扩展资料
uclinux表示micro-control linux.即“微控制器领域中的Linux系统”,是Lineo公司的主打产品,同时也是开放源码的嵌入式Linux的典范之作。uCLinux主要是针对目标处理器没有存储管理单元MMU(Memory Management Unit)的嵌入式系统而设计的。它已经被成功地移植到了很多平台上。由于没有MMU,其多任务的实现需要一定技巧。