Performance 是否可以“;中止”;当从内存加载寄存器而不是触发页面错误时?

Performance 是否可以“;中止”;当从内存加载寄存器而不是触发页面错误时?,performance,x86,cpu-architecture,page-fault,Performance,X86,Cpu Architecture,Page Fault,我在想“ “”是一个相关的问题,从另一个角度看问题,但没有解决方案 我希望能够将内存中的一些数据加载到寄存器中,但如果内存当前已被分页,则加载将中止,而不是出现页面错误。我需要代码在Windows和Linux上的用户空间中工作,而不需要任何非标准权限 (理想情况下,我也希望在TLB故障时中止。)TXT-NI功能的RTM(受限事务内存)部分允许抑制异常: 事务区域中必须暴露于软件的任何故障或陷阱都将被抑制事务性 执行将中止,执行将转换为非事务性执行,就像故障或陷阱从未发生过一样 发生。 […] 事

我在想“

“”是一个相关的问题,从另一个角度看问题,但没有解决方案

我希望能够将内存中的一些数据加载到寄存器中,但如果内存当前已被分页,则加载将中止,而不是出现页面错误。我需要代码在Windows和Linux上的用户空间中工作,而不需要任何非标准权限

理想情况下,我也希望在TLB故障时中止。)

TXT-NI功能的RTM(受限事务内存)部分允许抑制异常:

事务区域中必须暴露于软件的任何故障或陷阱都将被抑制事务性 执行将中止,执行将转换为非事务性执行,就像故障或陷阱从未发生过一样 发生。
[…]
事务执行期间发生的同步异常事件(#DE、#OF、#NP、#SS、#GP、#BR、#UD、#AC、#XM、#PF、#NM、#TS、#MF、#DB、#BP/INT3)可能导致执行不以事务方式提交,以及 需要非事务性执行。这些事件被抑制,就好像它们从未发生过一样

我从未使用过RTM,但它的工作原理如下:

xbegin fallback

  ; Don't fault here

xend

; Somewhere else
fallback:
  ; Retry non-transactionally
请注意,事务可能因多种原因而中止,请参阅《英特尔手册》第1卷第16.8.3.2章。 还要注意,RTM并不是无处不在的

除了RTM,我想不出另一种抑制负载的方法,因为它必须返回一个值或最终发出一个中止条件的信号(这与#PF相同)

TXT-NI功能的RTM(受限事务内存)部分允许抑制异常:

事务区域中必须暴露于软件的任何故障或陷阱都将被抑制事务性 执行将中止,执行将转换为非事务性执行,就像故障或陷阱从未发生过一样 发生。
[…]
事务执行期间发生的同步异常事件(#DE、#OF、#NP、#SS、#GP、#BR、#UD、#AC、#XM、#PF、#NM、#TS、#MF、#DB、#BP/INT3)可能导致执行不以事务方式提交,以及 需要非事务性执行。这些事件被抑制,就好像它们从未发生过一样

我从未使用过RTM,但它的工作原理如下:

xbegin fallback

  ; Don't fault here

xend

; Somewhere else
fallback:
  ; Retry non-transactionally
请注意,事务可能因多种原因而中止,请参阅《英特尔手册》第1卷第16.8.3.2章。 还要注意,RTM并不是无处不在的


除了RTM,我想不出另一种抑制负载的方法,因为它必须返回一个值或最终发出一个中止条件的信号(这与#PF相同)

不幸的是,在x86(或我所知的任何其他ISA)上,没有指令只查询TLB或当前页表,并在寄存器中查询结果。也许应该有,因为它可以非常便宜地实现

(对于查询虚拟内存中是否有分页的页面,有一个Linux系统调用,该调用为一系列起始页面生成当前/不存在的位图(给定为
void*start
/
size\u t length
。这可能类似于HW页面表,因此可能可以让您在接触内存之前避免页面错误,但与TLB或缓存无关。并且可能不排除软页面错误,只排除硬页面错误。当然,这只是当前的情况:页面可能被逐出在查询和访问之间。)


像这样的CPU功能有用吗?在一些情况下可能有用 这样的东西很难用在有回报的地方,因为每一个“错误”尝试是没有完成任何有用工作的CPU时间/指令。但这样的情况可能是一个胜利,当您不关心遍历树/图的顺序时,一些节点可能在缓存、TLB中处于热状态,甚至只有RAM,而其他节点处于冷状态,甚至被分页到磁盘

当内存紧张时,触摸一个冷页面甚至可能在您访问它之前退出当前的热页面

普通CPU(如现代x86)可以进行推测性/无序的页面漫游(以填充TLB条目),当然也可以推测性地加载到缓存中,但不会出现页面错误。页面错误是由内核在软件中处理的。页面错误不能推测性地发生,而是序列化(CPU不重命名权限级别)

所以软件预取可以便宜地让硬件在您触摸其他内存时填充TLB和缓存,如果您要触摸的第二个内存是冷的。如果它是热的,而您先触摸冷的一面,这是不幸的。如果有一种便宜的方法来检查热/冷,可能值得使用它始终走正确的路(至少在第一步)当一个指针是热的,另一个指针是冷的时,按遍历顺序。除非只读事务非常便宜,否则实际上不值得使用Margaret的聪明答案

如果您有两个指针,最终将取消引用,其中一个指针指向一个已被调出的页面,而另一个指针处于热状态,最好的情况是以某种方式检测到这一点,并让操作系统在您遍历RAM中已经存在的一侧时,从后台磁盘开始在一个页面中进行分页(例如,使用Windows)
PrefetchVirtualMemory
或Linux
madvise(MADV_将需要)
。请参阅OP的其他问题的答案:)

这将需要一个系统调用,但系统调用非常昂贵,并且会污染缓存和TLB,特别是在当前x86上,Spectre+熔毁缓解会增加数千个时钟周期。因此,不值得为树中的每对指针中的一个进行VM预取系统调用。如果所有指针在RAM中。


CPU设计的可能性 就像我说的,我不认为现在的国际会计准则有这个,但我认为b