2017-07-09 206 views

回答

3

monitor指令使用RAX/EAX/AX中指定的地址设置地址监视硬件。 来自Intel的报价
监视器的状态由指令mwait使用。

使用的有效地址大小(16,32或64位)取决于编码指令的有效地址大小(即,它可以用67h前缀覆盖,默认情况下它与代码大小相同) 。

rax/eax/ax中给出的地址是逻辑地址的偏移量部分,用于计算用于布​​防监视器的线性地址。
默认情况下,段部分为ds,段覆盖前缀可应用于更改段。
作为用于监视器的线性地址,分页不会影响监视。 ECX.MONITOR [位3] :

monitor(和mwait)指令的可用性由位CPUID.01H指示。
它是一个特权指令,但英特尔声称:

所述指令有条件地可用在水平大于0

所建议的方法更大的检测这样的条件是尝试执行monitor并处理最终的#UD异常(以自定义的方式将操作系统报告给用户级程序)。

被监控的地址范围必须是可回写缓存的。
由于涉及高速缓存和高速缓存一致性子系统,地址范围的大小根据最小和最大大小给出。
CPUID.01H:EAX [位15:0]给出了最小范围大小。这是由硬件监视器监视的区域的长度。然而,高速缓存一致性流量可能与更大尺寸的“块”(线)一起工作,并且如果后者被包括在前者中,则与被监视区域相邻的写入将触发它。
这产生了最大的范围大小,它可以在CPUID.01H:EBX [bit 15:0]中找到。
要正确使用monitor请确保所监视的数据结构符合最小范围大小,但也要确保没有代理在其最大范围大小范围内的地址旁写入数据。例如,如果最小范围大小为8个字节并且最大大小为16个字节,则确保所观察的结构适合8个字节,但是为其填充8个字节以达到总共十六个字节,以便不从其写入第8到第16个字节出现。

在单个集群系统中,上述两个值是相等的。我的都是64字节。
BIOS负责报告多集群系统中的IA32_MONITOR_FILTER_LINE_SIZE中的高速缓存一致性行大小。

以指令排序和访问权限为目的,monitor是一个负载。

monitor允许程序员指定提示扩展
扩展名在ecx中指定,而提示在edx中。
不支持的扩展引发#GP异常,不支持的提示将被忽略。
我不知道任何扩展的或暗示为monitor,英特尔手动报告

对于奔腾4处理器 (家族15,模型3),没有扩展或提示中定义。

我认为这条线一般是真的,它只是一个过时的处理器模型。
此外,monitor报告#GP If ECX ≠ 0.

伪码布防的监视器,无事后检查其状态(与mwait)不会造成任何伤害。

本质是void _mm_monitor(void const *p, unsigned extensions,unsigned hints)


一旦监控布防,它可以触发不同的条件:

  • 外部中断:NMI,SMM,INIT,BINIT,MCERR
  • 故障,中止包括机器检查
  • 建筑TLB失效,包括写入CR0,CR3,CR4和某些MSR写入
  • 由于快速系统导致的自愿转换打电话远调用
  • 屏蔽中断(如果允许)
  • 在监视地址范围

写监视的状态是不是程序员可见的,但它可以与mwait进行测试。
mwait进入实现定义的低功耗状态,直到显示器处于触发状态。
如果显示器未处于布防状态或已被触发,则mwaitnop,否则会使处理器停止执行指令,直至触发监视器。

Hardware monitor status and MONITOR/MWAIT interaction

mwait也可以给予扩展提示
扩展设置为ecx,提示eax
在撰写的唯一扩展的时间是:即使掩蔽

位0款待处理器中断,如中断事件(例如,即使EFLAGS.IF = 0)。可以设置仅当 CPUID.05H:ECX [位1] = 1
位31-1保留

的提示允许程序员指定实现中定义低功率模式。

位3:0子的C状态C内通状态,通过位指示[7:4]
位7:4目标C状态
的值0表示C1; 1表示C2等等
价值01111B的装置C0
注:MWAIT扩展目标C状态是特定处理器的C状态,不ACPI C-状态

的子状态的数目C模式(并且因此可用性)在CPUID.05h.EDX给出:

位03 - 00:使用MWAIT支持C0 *子C状态的数量。
位07-04:使用MWAIT支持的C1 *子C状态的数量。
位11-08:使用MWAIT支持的C2 *子C状态的数量。
位15-12:使用MWAIT支持的C3 *子C状态的数量。
位19-16:使用MWAIT支持的C4 *子C状态的数量。
位23 - 20:使用MWAIT支持的C5 *子C状态的数量。
位27 - 24:使用MWAIT支持的C6 *子C状态的数量。
位31-28:使用MWAIT支持的C7 *子C状态的数量。

请注意,将CPU置于高于C1的状态会禁用其他线程,因此触发监视器的写入操作必须来自其他代理。

内在是void _mm_mwait(unsigned extensions, unsigned hints)


monitor/mwait机械引入帮助线程之间的同步,它是不适合于监测访问的存储器范围,因为所述触发条件包括频繁发生的事件。
mwait始终强制检查是否已写入监控的范围。
有一个example here其中模式是如下:

  1. 的观看结构与一个特定的值(比如0)进行初始化。
  2. 使用monitor/mwait对。
  3. 在稍后的某个时刻,另一个再次向监视的结构写入一个特定的值(比如1)。
  4. 监视器被触发并mwait“返回”,被监视的结构值与1(发生写入),并且如果它不等于执行跳回2.

一些样品,未测试伪代码可能是:

struct MonitoredType 
{ 
    int (*event)(struct MonitoredType const* m);    /*Return 0 to keep monitoring*/ 
    struct AnyType data;        /*Less, in size, than MIN_MONITOR_RANGE*/ 
    char padding[MAX_MONITOR_RANGE - sizeof(AnyType)]; 
}; 

void wait_for_write(struct MonitoredType const* m) 
{ 
    /* This may miss a write if it happens before MONITOR, beware of race conditions if necessary */ 
    do 
    { 
    _mm_monitor(&m->data, 0, 0); 
    _mm_mwait(0, 0); 
    } while (! m->event(m)); 
} 

必须小心,以确保mwait退出条件是写,而不是其他的事件之一。
这就是函数指针event的原因。

为了监控对线性地址的写/读操作,可以使用调试寄存器
请参阅Intel manual 3的第17章,并检查您的OS文档以正确使用这些寄存器。


含义:与eax设置为01H执行cpuid并测试位的ecx 3之后。请注意,IA32_MISC_ENABLE允许操作系统或固件禁用monitor/mwait

+0

我猜想最大范围至少有一个64B的缓存行,以防您想要为您的示例使用更真实的数字。一个更可能的例子是min = 64和max = 128,在某些外层缓存使用较大行的系统上。 (IIRC,P4在某些缓存级别使用了128B行)。 –

相关问题