代码之家  ›  专栏  ›  技术社区  ›  Rahul Nanwani

根据实际、用户和系统时间比较两种不同的进程

  •  1
  • Rahul Nanwani  · 技术社区  · 8 年前

    我已经在SO上找到了关于真实时间、用户时间和系统时间的其他答案。在这个问题上,除了理论之外,我还想了解两个不同过程所报告的时间的实际含义,以完成相同的任务。

    我有一个python程序和一个nodejs程序 https://github.com/rnanwani/vips_performance 两者都处理一组输入图像,并对其进行处理以获得不同的输出。两者都使用libvips实现。 这是两个人的时间

    蟒蛇

    真实的 1米17.253秒
    使用者 1米54.766秒
    系统 0米2.988秒

    节点JS

    真实的 1米3.616秒
    使用者 3分25.097秒
    系统 0米8.494秒

    实时(根据其他答案,NodeJS的挂钟时间较短,根据我的理解,这意味着从输入到输出的整个进程在NodeJS上完成的速度要快得多。但与Python相比,用户和系统时间都非常高。此外,使用htop实用程序,我发现Node JS进程在整个进程中的CPU使用率约为360%,最大化4个内核。另一个是Pythone在整个过程中,CPU使用率为250%到120%。

    我想了解一些事情

    1. 较小的实时时间和较高的用户+系统时间是否意味着进程(在本例中为节点)更有效地利用CPU来更快地完成任务?
    2. 这些时间的实际意义是什么?随着请求数量的增加,哪种时间更快/更好/更容易扩展?
    5 回复  |  直到 8 年前
        1
  •  1
  •   jcupitt    5 年前

    我猜想节点一次运行多个vip管道,而python严格地一个接一个地运行。管道启动和关闭大多是单线程的,所以若节点同时启动多条管道,正如您所观察到的,它可能会节省一些时间。

    您以随机访问模式加载JPEG图像,因此整个图像将用libjpeg解压缩到内存中。这是一个单线程库,因此您永远不会看到超过100%的CPU使用率。

    接下来,执行resize/rotate/crop/jpegsave。在执行这些操作时,调整大小将很好地执行,CPU负载随着减少的平方而增加,旋转太简单,对运行时没有太大影响,裁剪是即时的。虽然jpegsave是单线程的(当然),但是vip在后台线程和write-behind缓冲区中运行它,所以您实际上可以免费获得它。

    我在我的台式PC上尝试了你的程序(六个超线程内核,12个硬件线程)。我懂了:

    $ time ./rahul.py indir outdir
    clearing output directory - outdir
    real    0m2.907s
    user    0m9.744s
    sys 0m0.784s
    

    看起来我们看到的是9.7/2.9,或者线程速度提高了3.4倍,但这很容易让人误解。如果我将vips线程池大小设置为1,您会看到更接近于真正的单线程性能(尽管它仍然使用jpegsave write-behind线程):

    $ export VIPS_CONCURRENCY=1
    $ time ./rahul.py indir outdir
    clearing output directory - outdir
    real    0m18.160s
    user    0m18.364s
    sys 0m0.204s
    

    所以我们真的得到了18.1/2.97,或6.1倍的加速。

    基准比较困难,真实/用户/系统可能很难解释。你需要考虑很多因素:

    • 核心数和硬件线程数
    • CPU功能,如SpeedStep和TurboBoost,它将根据热负荷上下计时核心
    • 程序的哪些部分是单线程的
    • IO负载
    • 内核调度程序设置

    我相信还有很多我已经忘记了。

    如果您好奇的话,libvips有自己的分析器,可以帮助您更深入地了解运行时行为。它可以显示各种工作线程的图形,它们在同步中花费了多长时间,管理时间,实际处理像素的时间,何时分配内存,以及何时再次释放。这里有一篇关于它的博客文章:

    http://libvips.blogspot.co.uk/2013/11/profiling-libvips.html

        2
  •  1
  •   Mike    8 年前

    较小的实时时间和较高的用户+系统时间是否意味着进程(在本例中为节点)更有效地利用CPU来更快地完成任务?

    这并不一定意味着他们能更有效地利用处理器。

    • 越高 使用者 时间意味着节点使用了更多的用户空间处理器时间,从而更快地完成任务。正如Luke Exton所说,cpu在“您编写/可能查看的代码”上花费的时间更多

    • 越高 系统 时间意味着会发生更多的上下文切换,这从您的htop利用率数据可以看出。这意味着调度程序(内核进程)在操作系统操作和用户空间操作之间跳转。这是查找CPU以安排任务所花费的时间。

    这些时间的实际意义是什么?随着请求数量的增加,哪种时间更快/更好/更容易扩展?

    执行问题是一个长期的问题,有许多警告。从python与Node的编号来看,我认为python线程更长,反过来做更多的内联处理。另一件需要注意的事情是python中的GIL。从本质上讲,python是一个单线程应用程序,您不能轻易摆脱这一点。这可能是Node实现更快(使用真实线程)的一个促成因素。 节点似乎被写入了正确的线程,并将许多任务分开。高度线程化应用程序的优点将有一个临界点,在这个临界点上,您将花费更多的时间为新线程寻找空闲的cpu,而不是实际工作。当这种情况发生时,您的python实现可能会再次变得更快。

        3
  •  1
  •   Mikhail Volskiy    8 年前

    较高的用户+系统时间意味着进程有更多的运行线程,正如您所注意到的那样,360%的用户使用了4核的几乎所有可用CPU资源。这意味着NodeJS进程已经受到可用CPU资源的限制,无法处理更多请求。此外,您最终可能在该计算机上运行的任何其他CPU密集型进程都会影响您的NodeJS进程。另一方面,Python进程并没有占用所有可用的CPU资源,可能可以根据大量请求进行扩展。

        4
  •  0
  •   Luke Exton    8 年前

    因此,这些时间本身并不可靠,他们说在CPU上执行一个操作需要多长时间。这与该机器上同时发生的任何其他情况紧密耦合,并且可能完全基于物理资源而剧烈波动。

    具体来说,就这些时间而言:

    • real=挂钟时间(开始到结束时间)
    • user=用户空间CPU时间(即您编写/可能查看的代码),例如节点/python库/您的代码
    • sys=内核CPU时间(即系统调用,例如从操作系统打开文件)

    具体来说,小实时意味着它实际上完成得更快。这是否意味着它确实做得更好,没有。例如,在同一时间机器上发生的事情可能会更少。

    就规模而言,这些数字有点无关紧要,这取决于体系结构/瓶颈。例如,就规模而言,特别是云计算而言,它是关于有效地分配资源和每个资源的相关IO,通常是(计算、磁盘、网络)。尽快处理此图像是否有助于缩放?大概您需要检查瓶颈和细节以确定。例如,它可能会淹没您的网络链接,然后在您达到计算限制之前,您会受到限制。或者,您可能会受到写入磁盘的速度的限制。

        5
  •  0
  •   MK.    8 年前

    其中一个潜在的重要方面是,没有人提到您的库(vip)本身将启动线程: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/using-threads.html

    libvips计算图像时,默认情况下会使用 线程,因为您有CPU内核。使用vips_concurrency_set()更改 这

    这解释了最初最让我惊讶的事情——NodeJS(据我所知)应该是非常单线程的,就像Python的GIL一样。这一切都与异步处理有关。 因此,vip的Python和Node绑定可能只使用不同的线程设置。这值得调查。

    (也就是说,快速查看并没有发现任何库中默认并发级别发生更改的证据)