为什么我的汇编代码在O(N * sqrt(N))时间运行时会以线性时间运行?

时间:2013-12-10 23:40:26

标签: linux performance assembly x86-64

所以我在汇编中编写素数生成器(学习语言),当我开始对程序进行基准测试时,我发现它是在线性时间而不是预期的O(N * sqrt(N))时间运行。

为什么会这样?

我仔细检查了代码并将其放在github上:https://github.com/kcolford/assembly_primes。它应该是相当可读的,但如果有人希望我更彻底地评论它(比如对每条指令的解释)我很乐意这样做,我只是觉得没有必要。

我正在使用的汇编器和链接器是GNU binutils中的汇编器和链接器,它是为运行linux内核的x86_64架构编写的。

1 个答案:

答案 0 :(得分:2)

通过实验测量Big-O复杂性很棘手。就像菲尔佩里所说的那样,通常有线性术语(或其他术语)压倒了“小”运行的主要 O ()术语。隐藏在big-O表示法中的这些额外术语总是存在于实际代码中,在分析实际运行时间时是必需的。

当我在测试机器上测量您的示例代码时,我得到了明显的非线性关系。由于名声不好,我无法发布情节,但这是一张表:

N (= n^2)     Time
  1000000    0.386
  4000000    1.846
  9000000    4.673
 16000000    9.275
 25000000   15.850
 36000000   24.690
 49000000   35.850
 64000000   49.887
 81000000   66.509
100000000   86.855

此外,我没有仔细查看您的算法的确切实现,但Sieve of Eratosthenes是O( n 日志日志 n ),而不是O( n sqrt( n ))。

另请注意,与数字运算相比,I / O通常非常昂贵。在您的情况下,在我的测试计算机上, n = 5000时,I / O几乎占总运行时间的30%。这将是运行时分析中的重要线性项。你必须彻底分析代码正在做的其他事情,以找出影响测量的其他因素。

相关问题