Intel系统编程指南第八章——8.7 Intel超线程技术架构

图8-4展示了一个支持Intel超线程技术的处理器的一个通用视图,使用源自Intel至强MP作为一个例子。这个对Intel超线程技术的实现由两个逻辑处理器构成(每个用一个独立的架构状态来表示),这两个逻辑处理器共享处理器的执行引擎和总线接口。每个逻辑处理器也有自己的高级可编程中断控制器(APIC)。

 

8.7.1 逻辑处理器的状态

 

以下特征是逻辑处理器架构状态的一部分。这些特征可以划分为三组:

1、为每个逻辑处理器被复制

2、被在一个物理处理器中的逻辑处理器(译者注:复数)共享

3、共享还是复制,依赖于实现

 

下列特征为每个逻辑处理器而被复制:

1、通用目的寄存器(EAX, EBX, ECX, EDX, ESI, EDI, ESP, 和 EBP)

2、段寄存器(CS, DS, SS, ES, FS, 和 GS)

3、EFLAGS和EIP寄存器。注意,为每个逻辑处理器的CS和EIP/RIP寄存器指向正被逻辑处理器执行的线程的指令流。

4、x87 FPU寄存器(ST0到ST7,状态字,控制字,标签字,数据操作指针,以及指令指针)。

5、MMX寄存器

6、XMM寄存器以及MXCSR寄存器

7、控制寄存器和系统表指针寄存器(GDTR, LDTR, IDTR,任务寄存器)

8、调试寄存器(DR0, DR1, DR2, DR3, DR6, DR7)和调试控制MSR(译者注:复数)

9、机器检查全局状态(IA32_MCG_STATUS)以及机器检查性能(IA32_MCG_CAP)MSR(译者注:复数)

10、热时钟调制和ACPI电源管理控制MSR(译者注:复数)

11、时间戳计数MSR(译者注:复数)

12、大部分其它MSR寄存器,包括页属性表(PAT)。见以下例外

13、本地APIC寄存器

14、Intel 64处理器上的额外通用目的寄存器(R8~R15),XMM寄存器(XMM8~XMM15),控制寄存器,IA32_EFER

 

下列特征被逻辑处理器共享:

1、存储器类型范围寄存器(MTRR(译者注:复数))

 

下列特征被共享还是被复制是实现指定的:

1、IA32_MISC_ENABLE MSR(MSR地址1A0H)

2、机器检查架构(MCA) MSR(除了IA32_MCG_STATUS和IA32_MCG_CAP MSR)

3、性能监视器控制器和计数器MSR

 

8.7.2 APIC功能性

 

当一个支持Intel超线程技术的处理器被初始化时,每个逻辑处理器被赋予一个本地APIC ID(见表10-1)。本地APIC ID为逻辑处理器充当一个ID,并被存储在逻辑处理器的APIC ID寄存器。如果两个或多个支持Intel超线程技术的处理器在一个MP系统中存在,那么在一个系统总线上的每个逻辑处理器被赋予一个唯一的本地APIC ID(见8.9.3小节)。

软件使用处理器间中断(IPI)消息工具与本地处理器通信。为APIC设置和编程与支持和不支持Intel超线程技术的处理器中的一样。见第10章。

 

8.7.3 存储器类型范围寄存器(MTRR)

 

在一个支持Intel超线程技术的处理器中的MTRR被本地处理器共享。当一个逻辑处理器更新MTRR的设置时,设置被自动地与相同物理包中的其它逻辑处理器共享。

架构要求所有基于Intel 64和IA-32处理器(这包括逻辑处理器)必须使用相同的MTRR存储器映射。这给了软件一个一致性的视野,独立于当前正在运行的处理器。见11.11小节。

 

8.7.4 页属性表(PAT)

 

每个逻辑处理器有其自己的PAT MSR (IA32_PAT)。然而,正如11.12小节所描述的,PAT MSR设置必须与系统中的所有处理器相同,包括逻辑处理器。

 

8.7.5 机器检查架构

 

由基于Intel NetBurst®微架构的处理器所实现的Intel HT技术的上下文中,所有机器检查架构(MCA)MSR(除了IA32_MCG_STATUS和IA32_MCG_CAP MSR)为每个逻辑处理器被复制。这允许在同一个物理处理器中的逻辑处理器同时被初始化、配置、查询、以及处理机器检查异常。这个设计与遵循第15章所给出指引的机器检查异常处理兼容。

IA32_MCG_STATUS MSR为每个逻辑处理器被复制,这样在处理器位域其在处理位域中的机器检查(MCIP)可以被用于探测部分MCA处理上的递归。此外,MSR允许每个逻辑处理器确定一个机器检查异常在进行中,独立于同一个物理包中另一个逻辑处理器的动作。

因为在一个物理包中的逻辑处理器对于共享资源是紧耦合的,所以在一个所给的物理处理器内所发生的机器检查错误,两个逻辑处理器都会被通知到。如果当一个致命错误被报告时,机器检查异常被允许,那么在一个物理包内的所有逻辑处理器被分派到机器检查异常处理。如果机器检查被禁止,那么逻辑处理器进入关闭状态,并断言IERR#信号。

 

当允许机器检查异常时,控制寄存器CR4中的MCE标志应该对每个逻辑处理器被置1。

 

在支持Intel超线程技术的Intel凌动处理器家族中,MCA工具在同一处理器核心上的所有逻辑处理器之间被共享。

 

8.7.6 调试寄存器和扩展

 

每个逻辑处理器有其自己的一组调试寄存器(DR0~DR7)以及其自己的调试控制MSR。这些可以被设置以为每个逻辑处理器独立地控制和记录调试信息。每个逻辑处理器也有其自己的最后分支记录(LBR)栈。

 

8.7.7 性能监视计数器

 

性能计数器以及它们伴随的控制MSR在一个基于Intel NetBurst微架构的处理器核心内的两个逻辑处理器之间被共享。作为一个结果,软件必须管理这些资源的使用。性能计数器中断、事件、以及精确的事件监视支持可以基于每个线程(每个逻辑处理器)被设置并分配。

见30.9小节对Intel至强MP中性能监视的讨论。

在支持Intel超线程技术的Intel凌动处理器家族中,性能计数器(通用目的与固定功能计数器)以及它们的伴随控制MSR为每个逻辑处理器被复制。

 

8.7.8 IA32_MISC_ENABLE MSR

 

IA32_MISC_ENABLE MSR (MSR地址1A0H)一般在一个支持Intel超线程技术的处理器的核心中的逻辑处理器之间共享。然而,在IA32_MISC_ENABLES MSR内的一些位域可以为每个逻辑处理器复制。在IA32_MISC_ENABLES内被共享或被复制的位域部分是依赖于实现的。软件应该小心地为系统中所有逻辑处理器上的被复制的位域编程以确保一致行为。

 

8.7.9 存储器次序

 

在一个支持Intel超线程技术的Intel 64或IA-32处理器中的逻辑处理器遵守与不支持超线程技术的Intel 64或IA-32处理器的相同的存储器次序规则(见8.2小节)。每个逻辑处理器使用一个处理器制定的模型,此模型可以进一步被定义为“带有存储缓存转运的写次序”。所有强化或弱化存储器次序模型以处理特定编程环境的机制应用到每个逻辑处理器。

 

8.7.10 串行化指令

 

作为一个通用规则,当在一个支持Intel超线程技术的处理器中的一个逻辑处理器执行一条串行化指令时,只有那个逻辑处理器受到此操作的影响。对此规则的一个例外是WBINVD、INVD和WRMSR指令的执行;以及当控制寄存器CR0中的CD标志的状态被修改时的MOV CR指令。这里,两个逻辑处理器都被串行化。

 

8.7.11 微代码更新资源

 

在一个支持Intel超线程技术的Intel处理器中,微代码更新工具在逻辑处理器之间共享;每个逻辑处理器都可以初始化一次更新。每个逻辑处理器都有其自己的BIOS签名MSR(IA32_BIOS_SIGN_ID在MSR地址8BH)。当一个逻辑处理器为一个物理处理器执行一次更新时,为常驻逻辑处理器的IA32_BIOS_SIGN_ID MSR以相同的信息被更新。如果逻辑处理器同时初始化一次更新,那么处理器核心提供必要的同步,以确保一次只执行一次更新。

 

注:某些处理器(在引入Intel 64架构和Intel NetBurst微架构之前)不支持同时对在同一个核心内的兄弟逻辑处理器同时加载微代码更新。Intel推荐一个公共的方法,微代码加载器使用9.11.6.3小节所描述串行技术。

 

8.7.12 自修改代码

 

支持Intel超线程技术的Intel处理器支持自修改代码,通过写数据来修改被cache的指令或当前正在执行的指令。它们也支持跨修改代码,在一个MP系统中由一个处理器生成的写修改另一个处理器上被cache的指令或正在执行的指令。见8.1.3小节。

 

8.7.13 实现特定的Intel HT技术工具

 

以下的非架构工具是在支持Intel超线程技术的IA-32处理器中实现特定的:

1、Cache

2、翻译后备缓存(TLB)

3、热监视工具

Intel至强处理器MP实现在以下小节中描述

 

8.7.13.1 处理器Cache

 

对于支持Intel超线程技术的处理器,Cache是被共享的。在一个逻辑处理器上执行的任意一条Cache操作指令对物理处理器的Cache层级有全局的影响。注意以下:

1、WBINVD指令——在被修改的数据写回到存储器之后,整个Cache层级被无效化。所有逻辑处理器停止执行,直到写回和无效化操作被完成之后。一个特殊总线周期被发送到所有Cache代理。WBINVD完成的时间量或周期数将根据不同Cache层级的大小或其它因素而有所不同。作为一个结果,WBINVD指令的使用可能会对中断/事件的相应时间有所影响。

2、INVD指令——整个Cache层级被无效化,而不将被修改的数据写回到存储器中。所有逻辑处理器停止执行,直到无效化操作被完成之后。一个特殊的总线周期被发送给所有Cache代理。

3、CLFLUSH指令——被指定的Cache行在被修改的数据被写回到存储器之后从Cache层级被无效化,并且一个总线周期被发送给所有Cache代理,而不管哪个逻辑处理器导致了Cache行被填充。

4、控制寄存器CR0中的CD标志——每个逻辑处理器都有其自己的CR0控制寄存器,从而,尤其CR0中自己的CD标志。两个逻辑处理器的CD标志被一起相“或”,这样,当任一逻辑处理器设置其CD标志时,整个Cache在名义上被禁止了。

 

8.7.13.2 处理器翻译后备缓存(TLB)

 

在支持Intel超线程的处理器中,数据Cache TLB被共享。指令Cache TLB在每个逻辑处理器中可能被复制,也可能被共享,依赖于不同处理器家族的实现细节。

TLB中的条目以一个指示逻辑处理器初始化翻译的ID被打标签。此标签甚至应用于为存储器分页而使用页全局特征,从而被标记为全局的翻译。见4.10小节。

当一个逻辑处理器执行一次TLB无效化操作时,只有为那逻辑处理器被打标签的TLB条目被保证被冲刷。这个协议应用于所有TLB无效化操作,包括对控制寄存器CR3和CR4的写,以及对INVLPG指令的使用。

 

8.7.13.3 热监视器

 

在支持Intel超线程技术的一个处理器中,逻辑处理器共享灾难性的电源关闭探测器以及自动热监视机制(见14.5小节)。共享导致以下行为:

1、如果处理器核心的温度上升超过预设的灾难性电源关闭温度,处理器核心中止执行,这导致了两个逻辑处理器均停止执行。

2、当处理器核心的温度上升超过预设的自动热监视器旅行(译者注:带有往返的)温度时,处理器核心的时钟速度被自动调整,这对两个逻辑处理器的执行速度都有影响。

对于软件控制的时钟调整,每个逻辑处理器有其自己的IA32_CLOCK_MODULATION MSR,允许时钟调整基于一个逻辑处理器被允许或禁止。典型地,如果软件控制的时钟调整将被使用,那么该特征必须对在一个物理处理器内的所有逻辑处理器被允许,并且调整任务周期必须为每个逻辑处理器设置为相同的值。如果任务周期在不同逻辑处理器之间不同,那么处理器时钟将被调整为所选择的最高任务周期。

 

8.7.13.4 外部信号兼容性

 

本小节描述了通过支持Intel超线程技术的一个处理器的一个引脚所接收到的外部信号上的限制,以及这些信号如何在这个处理器中的逻辑处理器之间被共享。

1、STPCLK#——一单个STPCLK#引脚在Intel至强处理器MP的物理包上被提供。外部控制逻辑为系统内的电源管理使用此引脚。当STPCLK#信号被断言时,处理器核心变迁到停止承认状态,在这个状态下指令执行被中止,但处理器核心继续应答窥探事务。不管逻辑处理器是活动还是中止,当STPCLK#信号被断言时,两个逻辑处理器上的执行都被停止,并且两个都不会响应中断。

在MP系统中,所有物理处理器上的STPCLK#信号一般被系绑在一起。作为一个结果,此信号同时影响系统内的所有逻辑处理器。

2、LINT0和LINT1引脚——一个支持Intel超线程技术的处理器只有一组LINT0和LINT1引脚,它们在逻辑处理器之间被共享。当这些引脚中的一个被断言时,两个逻辑处理器都响应,除非引脚已经在一个或两个逻辑处理器的APIC本地向量表中被屏蔽。

典型地,在MP系统中,LINT0和LINT1引脚不被用于给逻辑处理器传递中断。取而代之的是,所有中断通过I/O APIC被传递给本地处理器。

3、A20M#引脚——在一个IA-32处理器上,A20M#引脚典型地被为与Intel286处理器兼容而被提供。断言此引脚导致物理地址的位20对所有外部总线存储器访问被屏蔽(迫使为零)。支持Intel超线程的处理器提供一个A20M#引脚,它影响物理处理器内的所有两个逻辑处理器的操作。

A20M#的功能性主要被老的操作系统所使用,并不被现代现代操作系统所使用。在更新的Intel 64处理器上A20M#引脚可能会缺失。

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是第五版《代码答案形式的C语言程序设计》第八章的例题答案: 8.1 ```c #include <stdio.h> #define N 5 int main() { int a[N], max, i; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); max = a[0]; for (i = 1; i < N; i++) if (a[i] > max) max = a[i]; printf("max=%d\n", max); return 0; } ``` 8.2 ```c #include <stdio.h> #define N 5 int main() { int a[N], i; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); printf("Reverse array a:\n"); for (i = N - 1; i >= 0; i--) printf("%d ", a[i]); printf("\n"); return 0; } ``` 8.3 ```c #include <stdio.h> #define N 5 int main() { int a[N], i; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); printf("a[0]=%d, a[%d]=%d\n", a[0], N - 1, a[N - 1]); return 0; } ``` 8.4 ```c #include <stdio.h> #define N 5 int main() { int a[N], i, sum = 0; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); for (i = 0; i < N; i++) sum += a[i]; printf("sum=%d, average=%.2f\n", sum, (float)sum / N); return 0; } ``` 8.5 ```c #include <stdio.h> #define N 5 int main() { int a[N], i, temp; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); for (i = 0; i < N / 2; i++) { temp = a[i]; a[i] = a[N - i - 1]; a[N - i - 1] = temp; } printf("Reverse array a:\n"); for (i = 0; i < N; i++) printf("%d ", a[i]); printf("\n"); return 0; } ``` 8.6 ```c #include <stdio.h> #define N 5 int main() { int a[N], i, j, temp; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); for (i = 0; i < N - 1; i++) for (j = i + 1; j < N; j++) if (a[i] > a[j]) { temp = a[i]; a[i] = a[j]; a[j] = temp; } printf("Sort array a:\n"); for (i = 0; i < N; i++) printf("%d ", a[i]); printf("\n"); return 0; } ``` 8.7 ```c #include <stdio.h> #define N 5 int main() { int a[N], i, j, temp; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); for (i = 0; i < N - 1; i++) for (j = 0; j < N - i - 1; j++) if (a[j] > a[j + 1]) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } printf("Sort array a:\n"); for (i = 0; i < N; i++) printf("%d ", a[i]); printf("\n"); return 0; } ``` 8.8 ```c #include <stdio.h> #define N 5 int main() { int a[N], i; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); printf("Max 5 numbers in array a:\n"); for (i = 0; i < 5; i++) printf("%d ", a[i]); printf("\n"); return 0; } ``` 8.9 ```c #include <stdio.h> #define N 5 int main() { int a[N], i, j, temp; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); for (i = 0; i < N - 1; i++) for (j = 0; j < N - i - 1; j++) if (a[j] > a[j + 1]) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } printf("Median number in array a:\n"); printf("%d\n", a[N / 2]); return 0; } ``` 8.10 ```c #include <stdio.h> #define N 5 int main() { int a[N], i, j, temp; printf("Enter array a:\n"); for (i = 0; i < N; i++) scanf("%d", &a[i]); for (i = 0; i < N - 1; i++) for (j = 0; j < N - i - 1; j++) if (a[j] > a[j + 1]) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } printf("Mode number in array a:\n"); for (i = 0; i < N; i++) { int count = 0, k; for (j = i; j < N; j++) if (a[j] == a[i]) count++; for (k = i - 1; k >= 0; k--) if (a[k] == a[i]) break; if (k < 0 && count > 1) printf("%d ", a[i]); } printf("\n"); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值