- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
从here我知道英特尔近年来实现了几种静态分支预测机制:
80486年龄:永远不会被接受
奔腾4年龄:后退/未前进
像Ivy Bridge,Haswell这样的较新CPU已变得越来越无形,请参见Matt G's experiment here。
而且英特尔似乎不想再谈论它了,因为我在英特尔文档中找到的最新材料是大约十年前写的。
我知道静态分支预测远不及动态分支预测重要,但是在很多情况下,CPU将会完全丢失,并且程序员(带有编译器)通常是最佳指南。当然,这些情况通常不是性能瓶颈,因为一旦频繁执行分支,动态预测器就会捕获它。
由于英特尔不再在其文档中明确声明动态预测机制,因此GCC的builtin_expect()除了从热路径中删除不太可能的分支外,无能为力。
我对CPU设计并不熟悉,我也不知道英特尔如今使用哪种静态预测器确切的机制,但是我仍然觉得英特尔的最佳机制应该是清楚地记录他的CPU,“当动态预测器发生故障时我打算去哪里? ,前进或后退”,因为通常程序员是当时的最佳指南。
更新:我发现您提到的主题逐渐超出了我的了解。这里涉及一些动态预测机制和CPU内部细节,而我在两到三天内无法学习。因此,请允许我暂时退出您的讨论并重新充电。这里仍然欢迎任何答案,也许会帮助更多人
最佳答案
静态预测在现代设计中不受欢迎(甚至可能不存在)的主要原因是,与动态预测相比,静态预测在管道中发生得太晚了。基本问题是在提取分支方向和目标位置之前必须先知道它们,但是静态预测只能在解码之后(在提取之后进行)进行。
更详细地...
CPU流水线
简而言之,在执行期间需要从内存中获取指令,对这些指令进行解码,然后执行它们1。在高性能CPU上,这些阶段将进行流水线处理,这意味着它们通常都将并行发生-但在任何给定时刻都需要不同的指令。您可以阅读有关on Wikipedia的内容,但是请记住,现代CPU更复杂,通常具有更多的阶段。
在现代的x86上,使用复杂的变长指令集,可能仅在获取和解码指令中涉及许多流水线“阶段”,可能是六个或更多。这些指令也是superscalar,能够一次执行多个指令。这意味着当以最高效率执行时,将有许多指令处于飞行中,处于获取,解码,执行等各个阶段。
重定向获取
分支分支的效果在管道的整个初始部分(通常称为前端)上都可以感受到:跳转到新地址时,需要从该新地址获取,从该新地址解码等。我们说采取分支需要重定向获取。这对分支预测可以使用以有效执行的信息施加了某些限制。
考虑静态预测的工作原理:它查看指令,如果它是分支,则比较其目标以查看它是“向前”还是“向后”。所有这些必须在很大程度上发生在解码发生之后,因为那是知道实际指令的时间。但是,如果检测到分支并预测采取分支(例如,向后跳转),则预测器需要重定向取回,这是较早的流水线阶段。到在解码指令N
之后重新定向取回的时间时,已经有许多后续指令在错误(未采用)的路径上被取回和解码。这些必须扔掉。我们说在前端引入了气泡。
所有这一切的结果是,即使静态预测是100%正确的,但在采用分支的情况下,效率很低,因为前端流水线被取消了。如果在获取和解码结束之间有6个流水线级,则每个假定分支都会在流水线中引起6周期的冒泡,并且有一个很大的假设,即预测本身和清除不良路径指令的时间为“零周期”。
救援动态预测
但是,现代x86 CPU能够每个周期最多执行1个分支,即使对于完美预测的静态执行,它也比限制要好得多。为此,预测器通常无法使用解码后可用的信息。它必须能够重定向每个周期的提取,并且仅使用在最后一次预测后延迟一个周期的可用输入。本质上,这意味着预测器基本上是一个自包含的过程,仅将其自身的输出用作下一个周期的预测的输入。
这是大多数CPU上的动态预测器。它预测从下一个周期取回的位置,然后根据该预测来预测此后从该周期取回的位置,依此类推。它不使用有关已解码指令的任何信息,而仅使用分支的过去行为。它最终确实会从执行单元获得有关分支的实际方向的反馈,并根据分支的实际方向更新其预测,但是在相关指令通过预测器后的许多周期内,这基本上都是异步发生的。
加起来
所有这些都可以消除静态预测的用处。
首先,预测来得太迟了,因此,即使工作正常,也意味着在现代Intel上会出现6-8个周期的泡沫(实际上,这些是观察到的来自Intel所谓的“前端恢复者”的数据)。这极大地改变了成本/收益等式,根本无法做出预测。当您在获取预测之前具有动态预测器时,您或多或少希望进行一些预测,并且即使预测具有51%的准确性,也可能会有所收获。
但是,对于静态预测,如果要进行“实际”预测,则需要具有较高的准确性。例如,考虑一个8周期的前端恢复成本,而一个16周期的“完全错误预测”成本。假设在某些程序中,向后冷分支的获取频率是不向后分支的两倍。这应该是静态分支预测的胜利,它可以预测反向采用,对(相对于始终“预测” 2不采用的默认策略)?
没那么快!如果您假设8个周期的重新控制成本和16个周期的完全错误预测成本,那么它们最终将具有10.67个周期的相同混合成本-因为即使在正确预测的情况下,也存在8个周期的泡沫,但在静态情况下,没有相应的成本。
加上无静态预测的情况已经使静态预测的另一半正确了(前分支未采用的情况),静态预测的效用并不像人们想象的那么大。
为什么现在要更改?也许是因为管道的前端部分比其他部分更长,或者是因为动态预测器的性能和存储能力的提高意味着根本没有资格进行静态预测的冷支。改善静态预测器的性能还意味着,对于冷分支,反向预测的强度会降低,因为动态预测器会更频繁地记住循环(这是反向采样规则的原因)。
节省动态预测资源
这种变化也可能是由于与动态预测的交互作用:动态预测器的一种设计是根本不使用从未发现采用的分支的任何分支预测资源。由于此类分支是通用的,因此可以节省很多历史表和BTB空间。但是,这样的方案与静态预测器不一致,该静态预测器将反向分支预测为已采取:如果从不采用反向分支,则您不希望静态预测器选择该分支并将其预测为已采取,从而弄乱了您的行为节省未使用分支机构资源的策略。
1 ...然后还要做更多的事情,例如退休,但是-执行后发生的大部分情况对于我们这里的目的并不重要。
2我在这里用惊吓语录了“预测”,因为在某种程度上它甚至都不是预测:在没有任何相反预测的情况下,fetch和解码的默认行为是不采取,所以如果不这样做,它就是你得到的完全不进行任何静态预测,而动态预测器则不会告诉您。
关于x86 - 这些年来,英特尔为何改变静态分支预测机制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51822731/
我有以下MWE function f(p) ans = zeros(p, 2) return ans end ans = f(2) ans b=ans.+1.0 ans 起初,ans是正确的,
OWIN AppBuilder“UseStatic”位从本地文件系统传送文件,这在某些情况下很方便,但我希望它从我在应用程序启动时预先填充的内存中 IDictionary 传送内容。任何人都可以指出一
我是 JavaScript 新手。 我的代码允许我列出 JSON 文档的元素及其类型,并将所有元素连接到一个字符串 donnees_types 中。 问题是 JavaScript 中的 typeof
我想在每次刷新时更改主页上的背景图像。我怎样才能做到这一点?我认为 jquery 是可能的,但我不太清楚。 感谢您对此主题的任何帮助或评论。 最佳答案 我不知道“如何”,但我找到了以下链接: http
所以我已经在这上面花了几个小时了,老实说我完全陷入困境。我写了一个 for 循环来计算整数中的数字数量,但我发现一旦我输入 10 位以上的数字,除数值就会发生变化,而且我不明白为什么。我在互联网上搜索
当我在使用表面 View 的游戏 Activity 和使用膨胀菜单的其他 Activity 之间切换时,我会收到错误消息。 日志猫: 07-13 15:15:34.464: ERROR/Android
听说很简单 R*=f; G*=f; B*=f; 其中 f 是标量值 0 .. 1.0 或更大改变亮度的方法不太正确颜色,但我找不到一些代码片段获得更好的东西(无需太多学习色彩理论)也许有人可以在这里给
如以下链接所述:- How to get the ThreadPoolExecutor to increase threads to max before queueing? 我将队列实现更改为在进入
我只显示最初提供 20 分钟 slotMinutes 的日历。我试图让用户即时更改为 10 分钟的 slotMinutes。 我有一个触发以下代码的按钮: $('#calendar').fullCal
我的问题是:我的应用程序中有一个新闻列表(UITableView)当我点击 1 个"new"时,我打开它,里面有一个后退按钮,可以让我回到列表。现在的问题是我必须在滑动时实现"new"更改,所以我制作
我面临着与 I'm trying to install psycopg2 onto Mac OS 10.6.3; it claims it can't find "stdarg.h" but I ca
需要通过为 array2 中不存在的索引设置 visible false 来从 array1 创建一个新的 array3。 在下面的示例中,我有索引 0,2。所以对于 1,3,结果数组必须具有 vis
我有一个对象,类似这样 var Egg = function(){ this.test = $(.slider .label); $('.slider').slider({
我想改变 ScrollView 的宽度。首先,我这样做了: var scrollWidthConstraint: NSLayoutConstraint! 然后设置它: scrollWidthConst
我有两个动画,一个是“过渡”,它在悬停时缩小图像,另一个是 animation2,其中图像的不透明度以周期性间隔重复变化。 我有 animation2 在图像上进行,当我将鼠标悬停在它上面时,anim
我是一个 jQuery 新手,一直在尝试添加一个脚本来更改 div onClick 的 id。 这是一个jsfiddle example . $(function accept() { $("
我正在尝试更改用户输入的字母的大小写,并将该字母的小写和大写版本存储在变量中。我已经编写了下面的代码,但它在运行时遇到了问题。有人指出是什么导致了问题吗? #include #include #i
假设我有这段代码: char num[2] = {15, 240}; char* p_num; 现在,如果我理解的一切正确,数组中的位应该像这样对齐: 00001111 11110000 我的问题是
var html = '' + count + '' + i.Description + '' + i.Priority + '' + i.Status + 'johnsmith- ' + creat
我在虚拟机上安装了 minix3,并希望我可以操纵当前的队列选择算法,以便我可以将其从优先级顺序更改为包括随机分类的低优先级作业的优先级顺序。我发现我需要更改的代码部分在 proc.c 中,具体部分是
我是一名优秀的程序员,十分优秀!