为什么多线程python程序在ec2微实例上变慢?

时间:2013-07-04 18:31:40

标签: python multithreading python-2.7 amazon-ec2 sandbox

我正在使用在线Judge代码检查器。我的代码在python 2.7中使用多线程。我本地机器上的相同程序(i core 3 RAM 4GB)在1分10秒内评估大约1000个子分区。但是当我在ec2微型实例(大约600 MB RAM)上运行它需要的时候 40分钟(随机秒钟变得缓慢)。要知道我弄坏事情的原因。

  1. 首先,这是我的评估员的工作方式:

    • 我有一个主程序worker.py,它创建了多个线程
    • 主线程从文件(暂时)提取提交(一次10个)并将它们放入全局队列
    • 侧线程从队列中获取子部分(一个提交仅由一个线程评估)
    • 在副主题提交提交后,它将其发送到函数compile,该函数     将提交的可执行文件返回给该线程
    • 然后线程将此可执行文件发送到运行可执行文件的函数run     (使用具有已定义内存和时间限制的沙箱)并将可执行文件的输出写入文件,然后检查它 反对标准输出
    • 队列变空后,主线程再次提取10个提交并将它们放入队列

  2. 函数compilerun

    • 编译功能和运行功能将可执行文件和输出保存在已命名的文件中(分别)     像<thread_Name>.exe<thread_Name>.txt那样每个线程都有自己的文件     而且没有覆盖的问题。
    • 只有当编译函数的状态为OK(编译文件)时,线程才会运行函数,否则抛出编译错误 提交

  3. 现在我怀疑:

    • 由于资源有或因此而导致ec2执行缓慢的问题     到python的多线程。在我的脚本中,线程访问全局变量     例如运行中的队列(我把锁)和test.py(I dont put lock on it)     函数用字符标准输出检查输出(vimdiff like),     和mysandbox.py(libsandbox the sandbox)     和其他一些全局变量。由于python的GIL,它是慢工作。如果它     那么为什么它在我的本地机器上运行得很快。
    • 暂时我也提供相同的文件test.cpp(adds two numbers and prints result)     1000次。所以当我故意在这个文件中编译错误并运行我的主     关于ec2的程序它运行得非常快。从那我推断出编译和     我的程序的运行(编译和运行函数)占用主要时间,而不是线程     创造和管理。
  4. 我知道这是一个很大的问题,但任何帮助都非常感激(或者我必须保持对我的所有声誉的保证:))。

1 个答案:

答案 0 :(得分:2)

对于持续计算任务(按设计),微实例变得极其缓慢。

您编写的代码是多线程的,以利用整个“机器”的CPU资源来完成文件检索和编译等任务,这是性能的良好实践。

虽然这在物理计算机或具有保证配置硬件资源的虚拟机上有意义,但由于亚马逊分配资源的方式,在微实例上没有意义

Per Amazon's documentation,微实例仅针对短突发CPU操作而设计,因此如果您尝试使用多个占用CPU使用率的线程,则会遇到亚马逊自身施加的巨大瓶颈:

  

如果应用程序消耗的内存超过实例分配的CPU资源,我们会临时限制实例,以便它以低CPU级别运行。如果您的实例继续使用其所有分配的资源,其性能将下降。我们将增加限制其CPU级别的时间,从而增加允许实例再次爆发之前的时间。

查看我刚刚链接到的文档中的CPU使用率图表以获取更多详细信息。

为了证明这是问题所在,你可以简单地启动一个小实例并在那里运行你的判断软件 - 你应该体验到类似于台式机的显着改进。

TL; DR当尝试在微型实例上使用持续CPU时,它可能会变得不如旧的Palm Treo强大。