win10专业版激活指令,windows10指令集
在我之前的博客文章“问题:软件实际上使用新的指令集吗?”在中,我观察了几种不同的Linux *设置使用的指令种类,以及改变运行的处理器类型对每种设置的影响。作为这个职位的后续,现在我已经为Microsof t Windows 10做了同样的工作。在本文中,我将介绍Windows 10如何在各种处理器之间运行,以及它的行为与Ubuntu * 16相比如何。回到Ubuntu查看不同使用场景下的指令使用情况。
实验装置
就像之前一样,我在WindRiver Simics虚拟平台工具中使用了我们的“通用PC”平台,并使用了两种不同的处理器型号来运行它。一个型号是英特尔酷睿i7第1代处理器(代号“Nehalem”),另一个型号是英特尔酷睿i7第6代处理器(代号“Skylake”)。
使用这些不同的模型,我启动了Windows 10映像(准确地说是build 1511)。就像之前一样,我在开机的前60秒就跑完了,最后在一个闲置的桌面上。
下面是启动几个Windows 10目标从我的笔记本电脑收集统计数据的截图:
在启动过程中,我使用Simics工具环境来收集我看到的指令类型的统计数据。我计算每个助记符的指令用法,就像上一篇文章一样。另外,我在下面讨论的基础上,按照其他标准阅读了指令流。
跨越世代的指示
首先,我检查了在引导过程中出现的百分之一或更多的动态指令的所有指令。结果如下图所示:
我们在Windows数据中看到的与我们在之前的博客文章中看到的Ubuntu 16非常相似。各代处理器之间有一些微小的变化,但是不管处理器是什么,大多数相同的代码都可以运行。
对于Ubuntu和Windows等广泛使用的通用操作系统发行版来说,这并不意外。在之前的博文中,各代处理器之间最显著的区别是Yocto * Linux版本,这是有道理的。
Yocto允许您为自己构建一个Linux,当涉及到包含使用新指令集的代码时,它的默认值可以更激进,因为您通常不需要支持广泛的用户基础。对于Ubuntu和Windows 10来说,它们拥有广泛的用户基础和共同的目标,能够为大量用户提供可靠的工作。各代硬件之间的太多差异将使测试和质量控制更加困难。不像在自己的Linux上运行时,不要主动为单个系统进行优化。
反正我们看使用的指令,最常见的是move、compare、jump和basic算术。这与我们在Linux上看到的非常相似,但使用的确切指令确实有点不同。
比较Linux
当我们在这里更改操作系统时,编译器用于构建代码更改(从Linux *上的gcc到Windows上的Microsoft *编译器),以及如何完成函数调用和操作系统调用的约定。所有这些都会影响编译器中的指令选择过程,因此工作负载之间使用的实际指令可能会有所不同。事实上,我们甚至可以看到工作负载中使用的一些唯一的指令。在我们当前的数据集中有一些这样的例子。
Windows 10从不使用LEAVE或ENTER命令。正如我在之前的博客文章中所讨论的,旧的Linux 2.6 Busybox *安装程序确实使用了LEAVE,但是新的Linux发行版没有使用它。由于Windows 10是一个相当新的软件堆栈,它甚至不再使用LEAVE指令。
有一些使用Windows 10的说明,但是没有Linux的设置。最重要的一个是来自英特尔SIMD流指令扩展2(SSE2)指令集的MOVNTI指令。占Windows的三分之二以上!另外,除了上面提到的最常见的指令,Windows 10还使用了几个独特的没有任何Linux变种的矢量指令:PADDW、PSRLW、PMOVZXBW、PUNPCKHQDQ、PSUBW和PMADDWD。鉴于矢量指令集的丰富性,这并不奇怪。
Windows(而不是Linux)也使用原8086指令集的CMC(补充进位标志)指令。这同样适用于80386的BSR(位反向扫描)。它们并不常见(测量值低于0.01%),但有趣的是它们从未在Linux引导中使用过。
请注意,这只是关于操作系统的启动过程;应用程序的情况可能有所不同。其实我在Linux上做了一些其他的实验,结果如下。
矢量和SIMD
启动时,矢量指令不会用得太多。对于Windows来说,v1和v6处理器之间的差异并不是特别大——在Linux上这种差异更加明显。然而,当Windows 10与Ubuntu 16进行比较时,它变得更加有趣:
一般来说,Windows和Ubuntu在启动时使用矢量指令的比例是一样的(5%左右)。然而,这些向量指令以不同的方式分布。Windows使用更多的SSE2指令,而Ubuntu使用更多的MMX指令。Windows不会改变各代之间使用的指令,并且在v6处理器上几乎没有任何明显的英特尔高级矢量扩展指令集(AVX)的使用。
还有更多的事情
这种考察指令助记符的方法,其实只是一个简单的例子,你可以在虚拟平台中用工具运行的软件中观察到。这已经相当丰富了,但还有更多的观察和统计。作为Simics的用户,你可以编程工具来收集你想要的任何东西(只要它是虚拟平台的一部分)。
例如,以下是Windows 10在v6处理器上启动时指令大小的分配:
每条执行指令的平均大小约为3.73字节。请注意,这并不表示代码的大小。这代表了高速缓存系统和处理器解码器的压力。英特尔架构(IA)是一种经典的可变长度指令集。这里可以清楚地看到,指令长度的范围从1字节到14字节。值得注意的是,真正长的指令也非常少见。
分割指令的另一种方法是查看操作数类型和指令操作码。这是一个比上面使用的助记法更细粒度的分段。例如,MOV指令的20种最常见的变体如下:
这远远不是全部.还有许多其他特定的寻址模式在使用。这是一个典型的长尾分布:到目前为止,绝大多数的MOV操作是最常见的模式,同时频繁使用更复杂的模式也很重要。
注意,我们在这里看到所有大小的移动:仅仅因为这是一个运行在64位处理器上的64位Windows操作系统,并不意味着所有的操作实际上都是64位大小的。字节(8位)、字(16位)和双字(32位)操作也被使用。32位和64位一样常见。
在Linux桌面的向量和SIMD
当与我的一位同事讨论这些测量结果时,问题出现在一般矢量指令和AVX指令中,以及它们如何非常依赖于所使用的工作负载。操作系统引导不太可能用它来进行多个小密码和可能的一些高度优化的内存复制操作。但是他在交互使用系统时看到了一些其他的行为。所以,我做了另一个实验。我把Ubuntu的v6处理器放在那里,开机后开始运行一些交互软件。本质上,打开一个终端并启动一个新的Firefox进程。
从图中可以看出,AVX命令在桌面活动中被广泛使用——甚至包括更新的AVX2命令和FMA3命令。向量实际上包含了所有执行指令的12%以上,记住这包括了整个机器中的所有指令,而不仅仅是用户级代码或图形子系统中的代码。
结论
这是第二篇博客文章,用图表和数字详细说明了在不同处理器类型的许多不同工作负载中执行的不同类型的指令。这是一个像我这样的计算机架构呆子的数据集。然而,最有趣的是如何收集数字——使用Simics及其仪器功能。Simics可以模拟几乎任何系统,并允许非侵入式检查和调试。收集指令统计数据,例如,我在这里为处理器设计师、软件工程师、研究人员和学生提供有用的见解。
这里有一个简单的插件:Simics是免费提供给大学的。它是用于计算机体系结构、操作系统、网络、嵌入式系统、仿真、虚拟平台和底层编程的多功能工具。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。