- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
循环 ( Intel ref manual entry )减少 ecx/rcx,and then jumps if non-zero 。虽然速度很慢,但英特尔难道不能以低廉的成本让它变得更快吗? dec/jnz
已经macro-fuses into a single uop关于桑迪布里奇家族;唯一的区别是设置标志。
loop
关于各种微架构,来自 Agner Fog's instruction tables :
K8/K10:7 次操作
Bulldozer 系列/Ryzen:1 m-op(与宏融合测试和分支的成本相同,或 jecxz
)
P4:4 uops(与 jecxz
相同)
P6(PII/PIII):8 uops
Pentium M、Core2:11 uops
Nehalem:6 uops。 (11 表示 loope
/loopne
)。吞吐量 = 4c ( loop
) 或 7c ( loope/ne
)。
SnB 系列:7 uops。 (11 表示 loope
/loopne
)。 吞吐量 = 每 5 个周期一个,这与将循环计数器保留在内存中一样是瓶颈! jecxz
仅 2 uop,吞吐量与常规 jcc
相同
西尔弗蒙特:7 uops
AMD Jaguar(低功耗):8 uops,5c 吞吐量
通过 Nano3000:2 uops
解码器不能像lea rcx, [rcx-1]
一样解码吗/jrcxz
?那将是 3 uop。至少在没有地址大小前缀的情况下是这样,否则它必须使用 ecx
并截断RIP
至EIP
如果进行跳跃; 也许控制递减宽度的地址大小的奇怪选择解释了许多微指令?(有趣的事实: rep
-string 指令与使用 ecx
和 32 位地址具有相同的行为-尺寸。)
或者更好,只是将其解码为不设置标志的融合十进制分支? dec ecx
/jnz
SnB 上解码为单个 uop(它确实设置了标志)。
我知道真正的代码不会使用它(因为至少从 P5 或其他东西开始它就很慢),但 AMD 认为让 Bulldozer 变得更快是值得的。可能是因为这很容易。
<小时/>SnB家族的uarch是否容易快速loop
?如果是这样,他们为什么不呢?如果不是,为什么这么难?很多解码器晶体管?或者融合 dec&branch uop 中的额外位来记录它没有设置标志?那 7 个 uop 能做什么?这是一个非常简单的指令。
推土机有什么特别之处,快速loop
容易/值得吗?或者AMD是否浪费了一堆晶体管来制造loop
快速地?如果是这样,想必有人认为这是个好主意。
如果loop
速度很快,非常适合 BigInteger arbitrary-precision adc
loops, to avoid partial-flag stalls / slowdowns (请参阅我对我的答案的评论),或者您想要循环而不触及标志的任何其他情况。与 dec/jnz
相比,它还具有较小的代码大小优势。 。 (和 dec/jnz
仅 SnB 系列上的宏熔断器)。
在现代 CPU 上 dec/jnz
在 ADC 循环中正常,loop
对于 ADCX/ADOX 循环来说仍然很好(以保留 OF)。
如果loop
速度很快,编译器已经将其用作 CPU 上代码大小和速度的窥孔优化,而无需宏融合。
这并不能阻止我对使用 loop
的糟糕 16 位代码的所有问题感到恼火。对于每个循环,即使它们还需要循环内的另一个计数器。但至少不会那么那么糟糕。
最佳答案
1988年,IBM院士Glenn Henry他刚刚加入戴尔,当时该公司有几百名员工,在上任的第一个月,他就 386 内部结构进行了一次技术演讲。我们一群 BIOS 程序员一直想知道为什么 LOOP 比 DEC/JNZ 慢,所以在问答部分有人提出了这个问题。
他的回答很有道理。它与分页有关。
LOOP由两部分组成:递减CX,如果CX不为零则跳转。第一部分不能导致处理器异常,而跳转部分可以。其一,您可能会跳转(或失败)到段边界之外的地址,从而导致 SEGFAULT。对于两个,您可以跳转到已换出的页面。
SEGFAULT 通常意味着进程的结束,但页面错误则不同。当发生页面错误时,处理器会抛出异常,操作系统会进行内务处理,将页面从磁盘交换到 RAM 中。之后,它重新启动导致故障的指令。
重新启动意味着将进程的状态恢复到有问题的指令之前的状态。特别是在 LOOP 指令的情况下,它意味着恢复 CX 寄存器的值。有人可能认为您只需将 CX 加 1 即可,因为我们知道 CX 会递减,但显然,事情并没有那么简单。例如,查看这个erratum from Intel :
The protection violations involved usually indicate a probable software bug and restart is not desired if one of these violations occurs. In a Protected Mode 80286 system with wait states during any bus cycles, when certain protection violations are detected by the 80286 component, and the component transfers control to the exception handling routine, the contents of the CX register may be unreliable. (Whether CX contents are changed is a function of bus activity at the time internal microcode detects the protection violation.)
为了安全起见,他们需要在 LOOP 指令的每次迭代中保存 CX 的值,以便在需要时可靠地恢复它。
正是这种保存 CX 的额外负担使得 LOOP 如此缓慢。
与当时的其他公司一样,英特尔也在采用越来越多的 RISC。旧的 CISC 指令(LOOP、ENTER、LEAVE、BOUND)正在被逐步淘汰。我们仍然在手工编码的汇编中使用它们,但编译器完全忽略了它们。
关于performance - 为什么循环指令很慢?英特尔就不能有效地实现它吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35742570/
我是 PHP 新手。我一直在脚本中使用 for 循环、while 循环、foreach 循环。我想知道 哪个性能更好? 选择循环的标准是什么? 当我们在另一个循环中循环时应该使用哪个? 我一直想知道要
我在高中的编程课上,我的作业是制作一个基本的小计和顶级计算器,但我在一家餐馆工作,所以制作一个只能让你在一种食物中读到。因此,我尝试让它能够接收多种食品并将它们添加到一个价格变量中。抱歉,如果某些代码
这是我正在学习的一本教科书。 var ingredients = ["eggs", "milk", "flour", "sugar", "baking soda", "baking powder",
我正在从字符串中提取数字并将其传递给函数。我想给它加 1,然后返回字符串,同时保留前导零。我可以使用 while 循环来完成此操作,但不能使用 for 循环。 for 循环只是跳过零。 var add
编辑:我已经在程序的输出中进行了编辑。 该程序要求估计给定值 mu。用户给出一个值 mu,同时还提供了四个不等于 1 的不同数字(称为 w、x、y、z)。然后,程序尝试使用 de Jaeger 公式找
我正在编写一个算法,该算法对一个整数数组从末尾到开头执行一个大循环,其中包含一个 if 条件。第一次条件为假时,循环可以终止。 因此,对于 for 循环,如果条件为假,它会继续迭代并进行简单的变量更改
现在我已经习惯了在内存非常有限的情况下进行编程,但我没有答案的一个问题是:哪个内存效率更高;- for(;;) 或 while() ?还是它们可以平等互换?如果有的话,还要对效率问题发表评论! 最佳答
这个问题已经有答案了: How do I compare strings in Java? (23 个回答) 已关闭 8 年前。 我正在尝试创建一个小程序,我可以在其中读取该程序的单词。如果单词有 6
这个问题在这里已经有了答案: python : list index out of range error while iteratively popping elements (12 个答案) 关
我正在尝试向用户请求 4 到 10 之间的整数。如果他们回答超出该范围,它将进入循环。当用户第一次正确输入数字时,它不会中断并继续执行 else 语句。如果用户在 else 语句中正确输入数字,它将正
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我想要做的事情是使用循环创建一个数组,然后在另一个类中调用该数组,这不会做,也可能永远不会做。解决这个问题最好的方法是什么?我已经寻找了所有解决方案,但它们无法编译。感谢您的帮助。 import ja
我尝试创建一个带有嵌套 foreach 循环的列表。第一个循环是循环一些数字,第二个循环是循环日期。我想给一个日期写一个数字。所以还有另一个功能来检查它。但结果是数字多次写入日期。 Out 是这样的:
我正在模拟一家快餐店三个多小时。这三个小时分为 18 个间隔,每个间隔 600 秒。每个间隔都会输出有关这 600 秒内发生的情况的统计信息。 我原来的结构是这样的: int i; for (i=0;
这个问题已经有答案了: IE8 for...in enumerator (3 个回答) How do I check if an object has a specific property in J
哪个对性能更好?这可能与其他编程语言不一致,所以如果它们不同,或者如果你能用你对特定语言的知识回答我的问题,请解释。 我将使用 c++ 作为示例,但我想知道它在 java、c 或任何其他主流语言中的工
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我是 C 编程和编写代码的新手,以确定 M 测试用例的质因数分解。如果我一次只扫描一次,该功能本身就可以工作,但是当我尝试执行 M 次时却惨遭失败。 我不知道为什么 scanf() 循环有问题。 in
这个问题已经有答案了: JavaScript by reference vs. by value [duplicate] (4 个回答) 已关闭 3 年前。 我在使用 TSlint 时遇到问题,并且理
我尝试在下面的代码中添加 foreach 或 for 循环,以便为 Charts.js 创建多个数据集。这将允许我在此折线图上创建多条线。 我有一个 PHP 对象,我可以对其进行编码以稍后填充变量,但
我是一名优秀的程序员,十分优秀!