编写一个CPU密集型脚本来评估大致的CPU性能。

5

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

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、I/O效率等 - 非cPython程序
只是想确保我的方法能够正确地理解计算机之间的CPU性能。

假设有一个足够聪明的 Python(例如 Jython),f 类可能会被优化掉,因为似乎没有副作用。如果这是 Java 代码,我希望 JIT 可以将此代码优化掉。 - extraneon
@extraneon:嗯,将其优化为无副作用的副产品需要在一般情况下进行非常广泛的分析,并且在大多数实际代码中并不能节省太多,但会破坏这种基准测试。因此,我认为大多数JIT不会尝试删除它。我认为PyPy没有这样做,因为他们定期使用这种基准测试(例如,请参见http://morepypy.blogspot.com/2011/01/loop-invariant-code-motion.html),如果Jython比PyPy的JIT更聪明,我会感到惊讶。 - user395760
@anijhaw 感谢您的pystone建议,我会尝试的。 - Shekhar
4个回答

5

所有现有的基准测试都有什么问题?更复杂的基准测试可能更加稳健。您的天真方法存在的主要问题,我(请注意,我不是这个主题的专家)可以发现:

现代CPU非常复杂,采用非常聪明的优化技术。纯CPU计算速度的变化范围很大,取决于缓存有多少次帮助,程序有多少次导致流水线停顿,分支预测有多少次正确,还有可能有许多许多(这些只是我脑海中的一部分)。尽管在使用相同构建的相同可执行文件运行相同脚本进行相同的纯pure计算时,这些因素中的许多都不应该有任何影响,但是它们可能会有影响,而我们无法预测其程度-一旦更改其中任何一个参数(例如,由于不同的操作系统或架构而使用不同的构建),就可能会产生影响。
多线程操作系统永远不会让程序独占CPU。总会有其他程序同时运行并窃取时间,你无法真正知道x秒中有多少时间用于运行你的程序,有多少时间用于其他程序。至少,您应该多次运行程序,并将最小时间视为相对较少受其他程序干扰的时间。即使如此,您也需要在两个基准测试中具有大约相同的系统负载,以使数字有些意义。
至少CPython不会多线程,因此您只能获得一个内核的速度。
但是,由于您的要求似乎只是“仅仅是对CPU速度进行非常粗略的估计,充分意识到这些数字除了将CPU速度归入数量级之外,不能用于任何其他目的,即使如此,也必须加以怀疑,并且不会告诉任何实际应用程序的实际性能”,那么这可能还可以 - 只是不要认为它准确无误。不过,为什么不使用一个已经付出一些努力来缓解(而不是消除 - 没有人能做到)这些问题的硬化基准套件呢?
另外,请注意,timeit stdlib模块比手动使用秒表更容易使用,并尝试(并不是很努力,但这是一个开始)通过我提到的方法来解决第二个问题。

很好的解释,比我的更加健壮。 - taskinoor
同意使用timeit。我正在寻找对机器进行简单的CPU基准测试(不是100%科学和准确),针对“简单的Python脚本”,并考虑到Python语言的限制。 - Shekhar

1

你可以使用这些方法来大致了解情况。但那不会是精确的测量。脚本的执行时间将取决于许多其他因素,而不仅仅是CPU速度,例如使用的操作系统和解释器版本、当前系统负载、内存速度等等。我的建议是不要依赖这个。

编辑:只是一个注意事项。当涉及到性能时,许多人认为只有CPU速度很重要,但实际上几乎系统中的所有东西都可能影响性能。例如,如果您拥有高速CPU但低RAM(无论是大小还是速度),那么您将无法为CPU提供任何性能提升。


我知道其他因素也很重要,但我只对获取大致的CPU速度感兴趣。假设其余环境相同。 - Shekhar

1

本质上:不行。

基准测试是一个非常困难的问题,通常不值得自己去解决。这完全取决于你为什么关心它。你的方法肯定会给出一个非常粗略的估计,即系统A是否比系统B更好,但只有在结果差异很大的情况下才能做到。

你要做的是确定实际应用程序X在不同计算机上的性能如何。很少有真实世界的应用程序可以通过简单数学循环来近似。即使是这样(主要是科学计算),你最好还是在实际程序上测量时间。

真实世界的应用程序通常是非线性的,难以测量和模拟。这确实是一个已经被其他人解决得比你合理地解决得多的问题。

如果你想获得一个非常粗略的性能估计,那么可以按照你的方式进行。只是不要对结果抱有太大的信心,因为它们将远离你所谓的“科学”。


0

如果我理解你的意图正确(你可以稍微澄清一下 - 你到底是想测量或估计什么,处理器速度、代码速度还是其他什么目的,但如果我理解你的话),为什么不去查看timeit 是如何做的呢?


我正在尝试大致了解机器在运行“简单Python脚本”时的CPU效率。假设其他因素如内存、I/O、解释器和操作系统完全相同。是的,最终我可以/会使用timeit,但我只是想与其他人核对我的方法。 - Shekhar
1
我指的是去看一下http://hg.python.org/cpython/file/default/Lib/timeit.py,看看所有的考虑因素。 - Unreason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接