use*_*112 19 cpu performance x86 cpu-architecture tlb
我很难理解当翻译旁视缓冲区的前两个级别导致未命中时会发生什么?
我不确定特殊硬件电路中是否出现"页面行走",或者页表是否存储在L2/L3高速缓存中,或者它们是否只存在于主存储器中.
Pet*_*des 21
现代x86微体系结构具有专用的页面漫游硬件.他们甚至可以推测性地执行页面遍历以在TLB未命中实际发生之前加载TLB条目.Skylake甚至可以同时进行两次页面漫步,请参阅英特尔优化手册的2.1.3节.这可能与页面拆分负载惩罚从100个周期下降到5个周期有关.
一些微体系结构通过将未缓存的PTE推测性地加载但在第一次真正使用该条目之前使用存储到页面表进行修改,将其视为误推测,从而保护您免受推测性页面漫游的影响.即,将商店窥探到仅用于推测的TLB条目的页表条目.(Win9x依赖于此,而不是破坏重要的现有代码是CPU供应商所关心的.当Win9x编写时,当前的TLB失效规则尚不存在,所以它甚至不是一个错误;请参阅下面引用的Andy Glew的评论).AMD Bulldozer系列违反了这一假设,只给出了x86手册在纸上所说的内容.
页面遍历硬件生成的页表加载可以在L1,L2或L3高速缓存中命中. 例如,Broadwell perf计数器可以计算您选择的L1,L2,L3或内存中的页面遍历命中(即缓存未命中).Oprofile称之为PAGE_WALKER_LOADS.DTLB_L1.
由于页表使用基数树格式,页面目录条目指向页表条目表,因此PDE可能值得在页面遍历硬件内进行缓存. 这意味着您需要在可能认为不需要的情况下刷新TLB.根据这篇论文(第3节),英特尔和AMD实际上都是这样做的.他们说页面遍历加载(在AMD CPU上)忽略L1,但确实通过L2.(也许是为了避免污染L1,或减少读端口的争用).无论如何,这使得在页面漫游硬件内部缓存一些高级PDE更有价值,因为一个PDE涵盖了许多不同的翻译条目.
但请注意,x86不保证TLB条目的负缓存.将页面从无效更改为有效不需要invlpg.(因此,如果一个真正的实现确实想要进行那种负面缓存,它必须窥探或以某种方式仍然实现x86手册保证的语义.)
(历史记录:Andy Glew在电子设备上回答了这个问题的重复.S表示在P5及更早版本中,硬件页面遍历加载绕过了缓存.他还确认P6以及后来从正常的L1缓存加载.关于该问题的其他答案花了一些时间讨论解决硬件页面步行器被禁用时解决软件中TLB未命中的问题,导致它反过来陷入操作系统,如MIPS(见下文),这显然在P5上更快.它有一些有趣的链接最后,包括我在最后一段末尾链接的论文.)
正如Paul Clayton指出的那样(关于TLB未命中的另一个问题),硬件页面遍历的一大优势是TLB未命中并不一定会阻止CPU.(乱序执行正常进行,直到重新命令缓冲区填满,因为加载/存储不能退出.退休按顺序发生,因为CPU无法正式提交任何不应该发生的事情,如果以前的指示有问题.)
顺便说一下,可能有可能构建一个x86 CPU,通过捕获到微码来处理TLB未命中,而不是专用硬件状态机.这会(很多?)性能较差,也许不值得推测性地触发(因为从微代码发出uops意味着你不能从正在运行的代码发出指令.)
如果你在一个单独的硬件线程(有趣的想法),SMT风格中运行那些微操作,那么微编码TLB处理在理论上可能是非常糟糕的.你需要它比正常的超线程更少的启动/停止开销,用于从单线程切换到两个逻辑核心活动(必须等待事情消耗,直到它可以分区ROB,存储队列等),因为与通常的逻辑核心相比,它会经常启动/停止.但是,这是可能的,如果它不是真的一个完全独立的线程,但只是一些单独的退出状态,因此它中的缓存未命中不会阻止主代码的退出,并让它为临时使用一些隐藏的内部寄存器.它必须运行的代码由CPU设计者选择,因此额外的HW线程不必接近x86核心的完整架构状态.它很少需要做任何存储(可能只是为了PTE中访问的标志?),所以让这些存储使用与主线程相同的存储队列也不错.您只需将前端分区以混合TLB管理uops,并让它们与主线程无序执行.如果你可以保持每页分页的uop数量很小,那可能不会太糟糕.
在我所知道的单独的HW线程中,没有CPU实际上使用微代码进行"HW"页面遍历,但这是理论上的可能性.
在某些RISC架构(如MIPS)中,OS内核负责处理TLB未命中.TLB未命中导致执行内核的TLB未命中断处理程序.这意味着操作系统可以在这种体系结构上自由定义自己的页表格式.我想在写入后将页面标记为脏也需要陷阱到OS提供的例程,因为CPU不知道页表格式.
本章从操作系统教科书中解释了虚拟内存,页表和TLB.它们描述了软件管理的TLB(MIPS,SPARCv9)和硬件管理的TLB(x86)之间的区别.
如前所述,如果禁用HW页面漫游功能,则SW TLB管理是x86上的一个选项,并且在P5上获胜.
其他链接:
#PF用于计算页面遍历周期)英特尔开始运行页表的主要原因是通过缓存,而不是绕过缓存,是性能.在P6之前,页面表行走缓慢,没有从缓存中受益,并且是非推测性的.软件TLB错过处理的速度足够慢,这是一次性能上的胜利.P6加速TLB通过推测性地使用缓存,以及缓存中间节点(如页面目录条目)而错过了.
顺便说一句,AMD不愿意投机地进行TLB错过处理.我想因为他们受到DEC VAX Alpha架构师的影响.其中一位DEC Alpha建筑师相当强烈地告诉我,对于TLB未命中的投机处理,例如P6正在做的,是不正确的,并且永远不会奏效.当我在2002年左右到达AMD时,他们仍然有一个叫做"TLB Fence"的东西 - 不是围栏指令,而是在TLB错过的rop或微码序列中的一个点可能会或不会被允许发生 - 我害怕我不记得它究竟是如何运作的.
所以我认为推土机放弃了TLB和页面表走的一致性并不是那么多,因为推土机可能是第一台进行适度侵略性TLB未命中处理的AMD机器.
回想一下,当P6启动时,P5没有发货:现有的x86都是按顺序缓存旁路页面表,非推测性地,没有异步预取,而是通过缓存写入.即它们是缓存一致的,并且OS可以依赖于TLB条目的确定性替换.IIRC我为TLB条目以及数据和指令缓存编写了关于推测性和非确定性可缓存性的架构规则.您不能因为不遵循当时不存在的页表和TLB管理规则而责怪Windows,UNIX和Netware等操作系统.
IIRC我为TLB条目以及数据和指令缓存编写了关于推测性和非确定性可缓存性的架构规则.您不能因为不遵循当时不存在的页表和TLB管理规则而责怪Windows,UNIX和Netware等操作系统.
(2)我最大的遗憾之一是P6是我们没有提供内部指令TLB一致性支持.某些指令多次访问同一页面.同一指令中的不同uops可以为同一地址获得不同的翻译.如果我们给微码提供了保存物理地址转换的能力,然后使用它,事情会更好恕我直言.
(2a)当我加入P6时,我是RISC的支持者,我的态度是"让SW(微码)做到这一点".
(2a')最令人尴尬的错误之一与内存中的附加携带有关.在早期的微码.负载将进行,进位标志将被更新,并且存储可能出错 - 但进位标志已经更新,因此指令无法重新启动.//这是一个简单的微码修复,在写入进位标志之前进行存储 - 但是一个额外的uop足以使该指令不适合"中速"ucode系统.
(3)无论如何 - 主要的"支持"P6及其后代处理TLB一致性问题是在报告错误之前在退休时重新铺设页面表.这避免了在页表表示不应该有故障时通过报告故障来混淆操作系统.
(4)元评论:我认为任何架构都没有正确定义缓存无效TLB条目的规则.// AFAIK大多数处理器不会缓存无效的TLB条目 - 除了可能的Itanium及其NAT(非A Thing)页面.但是有一个真正的需要:推测性内存访问可能是通配地址,错过TLB,执行昂贵的页面表行走,减慢其他指令和线程 - 然后一遍又一遍地执行它因为"这是一个坏事实地址,不需要走页表"不记得.//我怀疑DOS攻击可以使用它.
(4')更糟糕的是,操作系统可能会做出隐含的假设,即永远不会缓存无效的转换,因此当从无效转换为有效时,不会执行TLB失效或MP TLB击落.//更糟糕^ 2:想象一下你正在缓存页表缓存的内部节点.想象一下,PD包含所有无效的PDE; 更糟糕的是,PD包含有效的d PDE,这些PDE指向全部无效的PT.您是否仍然可以缓存这些PDE?操作系统何时需要使条目无效?
(4'')因为使用处理器间中断的MP TLB射击是昂贵的,OS性能的人(就像我以前一样)总是在做"我们不需要在将PTE从无效变为有效之后使TLB无效"之类的参数.或"从有效只读到有效可写与不同地址".或者"我们不需要在将PDE更改为指向PTE与原始PT完全相同的不同PT之后使TLB无效......".//很多巧妙的论点.不幸的是并不总是正确
我的一些计算机架构师朋友现在支持连贯的TLB:侦听写入的TLB就像数据缓存一样.主要是允许我们构建更具侵略性的TLB和页表缓存,如果叶子和内部节点的有效和无效条目都是如此.而不必担心操作系统人员的假设.//我还没到那里:低端硬件太贵了 但可能值得在高端做.
我:神圣的废话,所以这是额外的ALU uop来自内存目标ADC,即使在Core2和SnB系列?永远不会猜到,但一直困惑于此.
Andy:通常当你"做RISC事情"时,需要额外的指令或微指令,仔细的顺序.然而,如果您具有"CISCy"支持,例如特殊硬件支持,以便单个指令是一个事务,要么全部完成,要么全部未完成,可以使用更短的代码序列.
类似的东西也适用于自我修改代码:我们想让自修改代码快速运行,因为试图使自己修改代码的遗留机制 - 排除管道以便序列化CPUID等指令 - 并不是那么简单窥探Icache和管道.但是,这又适用于高端机器:在低端机器上,传统机制足够快且便宜.
同上内存排序.高端窥探速度更快; 低端排水更便宜.
很难保持这种二分法.
特定实现必须实现与架构语句兼容但更强的规则,这是很常见的.但并非所有实现都必须以相同的方式执行.
这个评论主题是关于Andy对自修改代码和看到陈旧指令的问题的回答; 另一种情况是真正的CPU超出了纸上的要求,因为如果你没有跟踪分支机构之间发生的事情,那么总是更容易窥探EIP/RIP附近的商店而不是仅仅在分支指令上重新同步.
| 归档时间: |
|
| 查看次数: |
2135 次 |
| 最近记录: |