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

我已经通过关于真实,用户和系统时间的其他答案。 在这个问题上,除了这个理论之外,我有兴趣去理解两个不同的过程所报告的时代的实际意义,实现同样的任务。

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

python

真正的1分 17秒25秒
用户 1m54.766s
sys 0m2.988s

的NodeJS

真正的 1m3.616s
用户 3m25.097s
sys 0m8.494s

NodeJS的实时性(其他答案的挂钟时间更less),根据我的理解,从input到输出的整个过程在NodeJS上完成的速度要快得多,但用户和系统时间相当Python使用htop实用程序,我发现NodeJS进程在整个过程中占用了大约360%的CPU使用量,最大化了4个内核,另一方面,Python在整个过程中的CPU使用率从250%到120% 。

我想了解一些事情

  1. 较小的实时性和较高的用户+系统时间意味着进程(在这种情况下,节点)更有效地利用CPU来更快地完成任务?
  2. 这些时代的实际含义是什么?随着请求数量的增加,速度越快越好?

我的猜测是,节点一次运行多个vipspipe道,而python严格运行一个接一个。 stream水线的启动和closures主要是单线程的,所以如果节点一次启动几条stream水线,就可以节省一些时间。

你用随机存取模式加载你的JPEG图像,所以整个图像将被libjpeg解压缩到内存中。 这是一个单线程库,所以你永远不会看到100%以上的CPU使用率。

接下来,您可以resize/旋转/裁剪/ jpegsave。 通过这些操作,resize将会顺利进行,并且CPU负载会随着减less的平方而增加,旋转过于简单,不会对运行时产生太大影响,并且裁剪是即时的。 虽然jpegsave是单线程的(当然)vips在一个单独的后台线程中从一个后写缓冲区运行,所以你可以免费得到它。

我在台式电脑上试了你的程序(6个超线程核心,所以有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,则可以看到更接近真正的单线程性能的东西(尽pipe它仍然使用jpegsave写后台线程):

$ 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倍的加速。

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

  • 内核数量和硬件线程数量
  • 像SpeedStep和TurboBoost这样的CPUfunction,可以根据热负载对内核进行上下变频
  • 程序的哪些部分是单线程的
  • IO负载
  • 内核调度程序设置

我相信我忘记了很多其他人。

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

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

较小的实时性和较高的用户+系统时间意味着进程(在这种情况下,节点)更有效地利用CPU来更快地完成任务?

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

  • 较高的用户时间意味着节点正在利用更多的用户空间处理器时间,从而更快地完成任务。 正如卢克·埃克斯顿(Luke Exton)所说,CPU在“你写的代码/可能看的代码”上花费更多的时间

  • 更高的系统时间意味着更多的上下文切换发生,这从您的htop利用率数字是有意义的。 这意味着调度程序(内核进程)在操作系统操作和用户空间操作之间跳转。 这是查找CPU来安排任务的时间。

这些时代的实际含义是什么?随着请求数量的增加,速度越快越好?

执行的问题是一个长期的问题,并有许多警告。 我会从python vs Node号码中假设Python线程更长,并且进行更多的内联处理。 另外要注意的是Python中的GIL。 本质上python是一个单线程的应用程序,你不能轻易摆脱这一点。 这可能是促使Node实现更快(使用真正的线程)的一个因素。 该节点似乎被写入正确的线程,并分裂出许多任务。 高度线程化的应用程序的优点将有一个转折点,你会花更多的时间去寻找一个新的线程的空闲CPU,而不是实际的工作。 发生这种情况时,您的python实现可能会再次开始更快。

较高的用户数+系统时间意味着进程有更多的运行线程,正如您已经注意到的,360%使用了几乎所有可用的4核CPU资源。 这意味着NodeJS进程已经受到可用CPU资源的限制,无法处理更多的请求。 此外,您可能最终在该机器上运行的任何其他CPU密集型进程都将触发您的NodeJS进程。 另一方面,Python进程不占用所有可用的CPU资源,并且可能会随着多个请求进行扩展。

所以这些时间本身并不可靠,他们说这个过程花了多长时间在CPU上执行一个动作。 这与机器上同时发生的其他事情非常紧密地联系在一起,并可能完全基于物理资源而大幅波动。

具体来讲就是这个时候:

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

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

就规模而言,这些数字有点不相关,它取决于架构/瓶颈。 例如,就规模而言,特别是云计算而言,通常(计算,磁盘,networking)就是高效地为每个资源和相关的IO分配资源。 是否尽可能快地处理这个图像有助于规模? 也许? 您需要检查瓶颈和具体情况。 例如,它可能会淹没您的networking链接,然后在您达到计算限制之前,您就受到限制。 或者你可能会受到写入磁盘速度的限制。

其中一个潜在的重要方面就是没有人提到你的图书馆(vips)本身就会启动线程: http : //www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/使用-threads.html

当libvips计算图像时,默认情况下它将使用与CPU核心数量相同的线程。 使用vips_concurrency_set()来更改它。

这解释了最初让我感到吃惊的事情 – NodeJS应该(就我的理解而言)是相当单线程的,就像Python和GIL一样。 这完全是关于asynchronous处理和全部。 所以,vip的Python和Node绑定可能只是使用不同的线程设置。 这值得调查。

(也就是说,快速浏览并没有发现任何一个库中默认并发级别的变化)