这个'效率等级'分析装配说明意味着什么?

时间:2015-09-17 01:07:19

标签: c assembly

我的一个数据结构和算法问题是分析汇编代码并计算它的时间复杂度。我只是不理解我教授给我的例子。

使用http://gcc.godbolt.org/

将C代码转换为汇编指令

C代码是:

int main(void)
{
 int a[] = {11,-22,33}, length = 3, count = 0;

 for (int i = 0 ; i < length ; i++)
    if (a[i] > 5) 
       count++;
} 

汇编代码是:

main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $11, -32(%rbp)
    movl    $-22, -28(%rbp)
    movl    $33, -24(%rbp)
    movl    $3, -12(%rbp)
    movl    $0, -4(%rbp)
    movl    $0, -8(%rbp)
.L4:
    movl    -8(%rbp), %eax
    cmpl    -12(%rbp), %eax
    jge .L2
    movl    -8(%rbp), %eax
    cltq
    movl    -32(%rbp,%rax,4), %eax
    cmpl    $5, %eax
    jle .L3
    addl    $1, -4(%rbp)
    .L3:
    addl    $1, -8(%rbp)
    jmp .L4
.L2:
    movl    $0, %eax
    popq    %rbp
    ret

他的解释是:

最佳案例:指令数= 2 + n + 3 + 3(n + 1)+ 5n + 0 + 2n + 3 = 11n + 11

最坏情况:将0替换为n以获得指令数= 12n + 11

他的粗略解释是:

因为我们都近似并且也忽略了实际常数(例如11 * t0),所以更容易推理如下。 循环执行n次,循环内容占用恒定时间,因此总时间为O(n)。 大多数时候我们只使用粗略分析,这可以通过详细分析来证明。

我不明白这个解释。有人能更好地向我解释这个吗?

2 个答案:

答案 0 :(得分:4)

如果我正确地理解了您教授的问题版本,他会尝试教您算法量级和确切执行时间之间的区别。

确切的执行时间需要大量的工作才能计算出来。

  • 有一个循环将有10或11个指令, 取决于测试的价值。你最好的情况是没有元素 数组a []大于5(所以没有必要 递增);最糟糕的情况是所有元素都更大 超过5(所以他们都必须递增)。
  • 有预循环 setup,在数组中每个元素需要1条指令 初始化再加上5条指令。包括数组中每个元素的额外指令需要每个&#34;循环&#34; (实际上,数组中每个元素的指令)从[10或11]到[11或12]。
  • 前三个 循环的指令,执行循环测试并将比循环的其余部分执行一次;这使得额外执行指令开销,即使它们已包含在循环中的指令计数中。
  • 有循环后指令,还有3个开销指令。

当你把它们全部加起来时,你会得到最好和最坏的情况方程:11n + 11是每个数组元素11个指令+11个开销; 12n + 11是每个数组元素12个指令+11个开销。

在算法的数量级上,代码是非常可预测的,因此它易于计算。因为每个输入数据没有中断或多次传递,所以每个数组元素需要一个循环O(n)。如果(比较)它将每个元素与每个其他元素进行比较,因此必须具有n个元素的内部循环和n个元素的外部循环,那将是O(n ^ 2)。简单的排序程序往往就是这样。

我认为本课程的核心是认识到计算执行的准确时间 HARD 。这个小例子没有考虑内存总线的速度,测试数据是否适合处理器的缓存,以及其他可能影响执行时间的其他事情。通过比较可以很容易地理解一般数量级(尽管在复杂算法上,它仍然很难)。通常订单就是您所需要的。在极少数情况下,您需要进行详细分析,现在您已了解如何进行...但粗略分析对于您需要做的几乎任何事情都是足够好的。

在职业发展的正常世界中,只有专家通常需要关心逐个教学的时间安排。了解算法的顺序可以让您在更高层次上比较您的想法,并在更合理的时间内得到正确的答案。

希望这有帮助!

答案 1 :(得分:1)

让我重新说一下:

  

因为我们都近似并且也忽略了实际的常数(例如   11 * t0),更容易推理如下。

在谈论复杂性时,我们并不关心常量。换句话说,具有11*n指令的程序与具有12*n指令的程序O(n)具有相同的复杂性。

  

循环执行n次,循环内容不变   时间,所以总时间是O(n)。

循环执行n次。在这种情况下,n=length。在每次迭代中,我们评估a[i] > 5,如果为真,我们会进行添加,如果为假,我们不会。换句话说,我们要么做一个指示,要么不做。换句话说,循环的主体需要O(1)时间。如果您执行O(1)任务n次,则会导致O(n)复杂度。

  

大多数时候我们只使用粗略的分析,这是合理的   通过详细分析。

粗略分析是O(1)*n = O(n)。详细的分析是计算指示。

详细分析是指在最佳情况和最差情况下计算指令的时间。如果您获得相同的复杂性,在我们的案例中O(n),那么您已经证明您的粗略分析是正确的。

如果a[i] > 5始终为false,则此程序将执行最少的指令。然后你得到11n + 11个指令。

如果a[i] > 5始终为真,则此程序将执行最多指令。然后你得到12n + 11个指令。

当您删除常量时,两者都是n,因此我们对O(n)时间的估计是正确的。