编写一个CPU密集型脚本以评估CPU性能

5 投票
4 回答
4934 浏览
提问于 2025-04-16 15:52

我写了一个脚本,并在不同的机器上运行。脚本大致如下:

def f(n):
    x = None
    while n:
        x = simple_math(n)
        n -= 1
    return x

start = now()
f(BIGNUM)    
print now() - start   

在脚本的最后,它会打印出完成所花费的时间。这样的方法是否足够好,可以用来比较不同机器在运行简单的Python脚本时的实际CPU速度?

这里的“简单”是指这个脚本没有使用多进程模块,也没有其他任何技术来利用多核机器的优势。

这个问题不是关于:

  • 让Python程序运行得更快
  • 多进程模块
  • 全局解释器锁(GIL)、输入输出效率等
  • 非cPython程序

我只是想确认一下,我用来理解不同机器CPU性能的方法是否大致正确。

4 个回答

1

简单来说:不行。

性能测试是个很复杂的问题,通常自己去解决并不划算。这主要看你为什么在乎这个问题。你的方法可能会给出一个大概的估计,告诉你系统A是否比系统B好,但这只有在结果差异很大的时候才有意义。

你想要做的是了解现实中的应用程序X在不同电脑上的表现。实际上,现实中的应用程序很少能用简单的数学循环来近似描述。即使有(比如科学计算),你还是直接测量实际程序的运行时间更靠谱。

现实中的应用程序通常是非线性的,测量和模拟起来都很困难。这种问题其实已经被别人解决得比你自己去解决要好得多。

如果你只是想要一个大概的性能估计,那你可以按自己的方式来做。只是别对结果抱太大希望,因为它们离“科学”这个标准会有很大差距。

5

现有的各种基准测试到底有什么问题呢?那些更复杂的基准测试可能会稍微靠谱一点。根据我的观察(我并不是这个领域的专家),你简单的方法存在的主要问题有:

  • 现代的CPU非常复杂,使用了很多聪明的优化手段。一个完全依赖CPU的程序运行速度会因为很多因素而大相径庭,比如缓存能帮上多少忙、程序造成的管道停顿有多少、分支预测的准确率如何,还有很多其他因素(这些只是我随便想的)。虽然在使用相同版本的可执行文件、运行相同脚本进行相同的纯计算时,这些因素通常不会有太大影响,但一旦你改变了其中的任何参数(比如因为不同的操作系统或架构使用了不同的版本),这些因素就可能产生影响,影响的程度是我们无法预测的。
  • 多线程的操作系统永远不会让一个程序独占CPU。总会有其他程序同时在运行,抢占CPU时间,所以你无法确切知道在x秒中有多少时间是你的程序在运行,多少时间是其他程序在占用。至少,你应该多次运行一个程序,并把最短的时间作为相对较少受到其他程序干扰的时间。即便如此,你在进行基准测试时,两个测试的系统负载也要大致相同,这样数据才有点意义。
  • 至少在CPython中,它不会进行多线程处理,所以你只能利用到一个核心的速度。

不过,既然你的需求似乎只是“对CPU速度的非常粗略估计,完全意识到这些数字除了用来大致了解CPU速度的级别外,不能用于其他任何目的,即使如此也要谨慎对待,并且不能反映任何实际应用的性能”,那么这样也许可以接受——只是不要把它当成准确的数据。尽管如此,为什么不使用一个经过严格测试的基准套件呢?这些套件已经在努力减轻(而不是完全消除——没有人能做到这一点)这些问题。

另外,注意到timeit这个标准库模块比手动使用秒表要简单得多,并且它尝试(虽然不是很努力,但算是一个开始)通过我提到的方法来解决第二个问题。

1

你可以通过这些方法大致了解情况,但这并不是准确的测量。脚本的执行时间会受到很多因素的影响,不仅仅是CPU的速度,比如操作系统和解释器的版本、当前系统的负载、内存的速度等等。我的建议是不要太依赖这些数据。

补充说明:谈到性能时,很多人只关注CPU的速度,但其实系统中的几乎所有东西都可能影响性能。例如,如果你的CPU速度很快,但内存(无论是容量还是速度)很低,那么CPU的性能也不会有提升。

撰写回答