首页 » 网站推广 » php挪用tlb技巧_TLB缓存是个神马鬼若何查看TLB miss

php挪用tlb技巧_TLB缓存是个神马鬼若何查看TLB miss

duote123 2024-11-28 0

扫一扫用手机浏览

文章目录 [+]

虚拟内存

在用户的视角里,每个进程都有自己独立的地址空间,A进程的4GB和B进程4GB是完备独立不干系的,他们看到的都是操作系统虚拟出来的地址空间。
但是呢,虚拟地址终极还是要落在实际内存的物理地址上进行操作的。
操作系统就会通过页表的机制来实现进程的虚拟地址到物理地址的翻译事情。
个中每一页的大小都是固定的。
这一段我不想先容的太过于详细,对这个观点不熟习的同学回去翻一下操作系统的教材。

php挪用tlb技巧_TLB缓存是个神马鬼若何查看TLB miss

页表管理有两个关键点,分别是页面大小和页表级数

php挪用tlb技巧_TLB缓存是个神马鬼若何查看TLB miss
(图片来自网络侵删)
页面大小在Linux下,我们通过如下命令可以查看到当前操作系统的页大小

# getconf PAGE_SIZE4096

可以看到当前我的Linux机器的页表是4KB的大小。

页表级数页表级数越少,虚拟地址到物理地址的映射会很快,但是须要管理的页表项会很多,能支持的地址空间也有限。
相反页表级数越多,须要的存储的页表数据就会越少,而且能支持到比较大的地址空间,但是虚拟地址到物理地址的映射就会越慢。

为了帮助大家回顾这段知识,我举个例子。
如果想支持32位的操作系统下的4GB进程虚拟地址空间,假设页表大小为4K,则共有2的20次方页面。
如果采取速率最快的1级页表,对应则须要2的20次方个页表项。
一个页表项如果4字节,那么一个进程就须要(10485764=)4M的内存来存页表项。

如果是采取2级页表,如图:

图1.jpg

则只须要页目录1024个,页表项1024个,统共2028个页表管理条款,(20484=)8k就可以支持起4GB的地址空间转换。

更何况操作系统须要支持的可是64位地址空间,而且要支持成百上千的进程,这个开销会大道不可忍。

以是每个操作系统制订页表级数的时候都是在映射速率和页表占用空间中取折中。

Linux在v2.6.11往后,终极采取的方案是4级页表,分别是:

- PGD:page Global directory(47-39), 页全局目录

- PUD:Page Upper Directory(38-30),页上级目录

- PMD:page middle directory(29-21),页中间目录

- PTE:page table entry(20-12),页表项

这样,一个64位的虚拟空间,就须要:2^9 个PGD + 2^9 个PUD + 2^9 个PMD + 2^9 个PTE = 2048个页表数据构造。
现在的页表数据构造被扩展到了8byte。
仅仅须要(20488=)16K就可以支持起(2^48 =)256T的进程地址空间。

页表带来的问题

上面终于费劲扒了半天Linux虚拟内存的实现,我终于可以开始说我想说的重点了。

虽然16K的页表数据支持起了256T的地址空间寻址。
但是,这也带来了额外的问题,页表是存在内存里的。
那便是一次内存IO光是虚拟地址到物理地址的转换就要去内存查4次页表,再算上真正的内存访问,竟然须要5次内存IO才能获取一个内存数据!!

TLB应运而生

和CPU的L1、L2、L3的缓存思想同等,既然进行地址转换须要的内存IO次数多,且耗时。
那么干脆就在CPU里把页表尽可能地cache起来不就行了么,以是就有了TLB(Translation Lookaside Buffer),专门用于改进虚拟地址到物理地址转换速率的缓存。
其访问速率非常快,和寄存器相称,比L1访问还快。

我本来想实际看一下TLB的信息,但翻遍了Linux的各种命令,也没有找到像sysfs这么方便查看L1、L2、L3大小的方法。
仅仅供应下图供大家参考吧!
(谁假如找到了查看TLB的命令,别忘了分享给飞哥啊,感激!

图2.jpg

有了TLB之后,CPU访问某个虚拟内存地址的过程如下

1.CPU产生一个虚拟地址2.MMU从TLB中获取页表,翻译成物理地址3.MMU把物理地址发送给L1/L2/L3/内存4.L1/L2/L3/内存将地址对应数据返回给CPU

由于第2步是类似于寄存器的访问速率,以是如果TLB能命中,则虚拟地址到物理地址的韶光开销险些可以忽略。
如果想理解TLB更详细的事情机制,请参考《深入理解打算机系统-第9章虚拟内存》

工具

既然TLB缓存命中很主要,那么有什么工具能够查看你的系统里的命中率呢? 还真有

# perf stat -e dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses -p $PID Performance counter stats for process id '21047': 627,809 dTLB-loads 8,566 dTLB-load-misses # 1.36% of all dTLB cache hits 2,001,294 iTLB-loads 3,826 iTLB-load-misses # 0.19% of all iTLB cache hits

扩展

由于TLB并不是很大,只有4k,而且现在逻辑核又造成会有两个进程来共享。
以是可能会有cache miss的情形涌现。
而且一旦TLB miss造成的后果可比物理地址cache miss后果要严重一些,最多可能须要进行5次内存IO才行。
建议你先用上面的perf工具查看一下你的程序的TLB的miss情形,如果确实不命中率很高,那么Linux许可你利用大内存页,很多大牛包括PHP7作者鸟哥也这样建议。
这样将会大大减少页表项的数量,以是自然也会降落TLB cache miss率。
所要承担的代价便是会造成一定程度的内存摧残浪费蹂躏。
在Linux里,大内存页默认是不开启的。

个人公众年夜众号“开拓内功修炼”,打通理论与实践的任督二脉。

参考文献

Linux内核4级页表的演进什么是TLB和PCID?为什么要有PCID?为什么Linux现在才开始利用它?MMU内存管理单元
标签:

相关文章

php常量率低技巧_PHP 常量详解教程

PHP 常量常量是单个值的标识符(名称)。在脚本中无法改变该值。有效的常量名以字符或下划线开头(常量名称前面没有 $ 符号)。注释...

网站推广 2024-12-19 阅读0 评论0