2011-12-13 50 views
1

为什么程序不同部分中的相同汇编程序操作(例如多个)消耗不同的时间量?汇编程序操作的时间

P.S.我正在使用C++和反汇编程序。

+0

您是否有更具体的例子,您是否使用x86(_64?)?这有点含糊。这个问题更多的是关于微代码架构的问题。例如,您正在注册两个注册表或两个存储位置。这是你第一次在一段时间内使用变量导致缓存未命中,因为它是L(1-3)缓存。 – 111111

+0

64.在profiler中,例如,我看到“mulps%xmm11,%xmm5”。我想这是寄存器中的数据。 – klm123

+0

正确的如果我错了,但xmmXX是SSE寄存器,它正在执行该操作多达4个浮点数或一次2个双精度浮点数 – 111111

回答

4

有各种各样的原因,为什么同一种操作可以在现代处理器上有大量不同的性能。

  • 数据缓存缺失: 如果您的操作访问内存,它可能会去缓存在一个位置和其他地方产生高速缓存未命中。高速缓存未命中可以按照循环周期顺序执行,而简单的操作通常在几个周期内执行,所以这会使其慢得多。

  • 流水线停顿: 现代CPU通常流水线,所以指令(或一个以上)可被调度每个循环中,但它们通常需要一个以上的周期,直到结果是可用的。您的操作可能取决于另一个操作的结果,该操作在计划操作时未准备好,因此CPU必须等待生成结果的操作完成。

  • 指令高速缓存未命中: 指令流也被缓存,所以你可能会发现其中的一个位置CPU产生高速缓存未命中每次encounteres该位置(不太可能的事情,这将需要检测的时间的情况尽管运行时间的数量,指令缓存并不那么小)。

  • 分支预测失误: 另一种流水线失速。 CPU将尝试预测条件跳转将以何种方式进行,并推测性地执行该执行路径中的代码。如果它是错误的,它必须放弃这个推测性执行的结果,并从另一条路径开始。这可能会显示在探查器中另一路径的第一行。

  • 资源竞争:该操作可能不会依赖一个不avalible结果,但需要执行单元可能仍然被其他指令(占据一些指令是不是所有的处理器完全流水线,也可能是因为一些一种超线程或推土机共享FPU)。再次,CPU可能必须停止,直到设备空闲。

  • 页面错误:应该很明显。基本上是类固醇缓存小姐。如果访问的内存必须从磁盘重新加载它会花费周期

  • ...成千上万的:这样的例子不胜枚举,但是提点最有可能使我的opionon产生影响的那些。

+0

不要混淆分支预测和分支预测;-) –

+0

灰熊,感谢您的详细解释! – klm123

+0

梦幻般的答案。 –

2

我假设你问的是完全相同的指令应用于相同的操作数。

可能会产生巨大性能影响的一个可能原因是,操作数是否在CPU高速缓存中可用,或者是否必须从主RAM中获取操作数。

这只是一个例子;还有很多其他潜在的原因。对于现代的CPU,通过查看代码很难弄清楚给定指令需要多少个周期。

5

这个问题很模糊,但一般在一个现代化的CPU,你不能指望操作具有恒定的执行时间,因为很多因素会影响这一点,包括但不限于:

  • 分支预测故障
  • 高速缓存未命中
  • 流水线
  • ...
+0

+1,不要忘记交换文件。 – sharptooth

+1

我喜欢我的AVR,其中'mul'总是需要相同的周期数。哦,等等..它没有'mul'。 –

+0

@ noah1989:不要尝试图片asm。它使AVR看起来很棒。 – 111111

1
  1. 在剖析器中,例如,我看到“mulps%xmm11,%xmm5”。我想这是在寄存器

xmmXX是SSE指令的数据。 mulps是精确单数,它取决于您是否将SSE乘法与正常标量乘法进行比较。在这种情况下,这是可以理解的。

我们确实需要更多信息才能更好地回答一大堆asm和您的配置文件数据。

如果只是这个指令很慢?或一块指令,也许它从未对齐的内存中加载,或者你得到缓存未命中,管道危险和其他许多可能性。