关于实际,用户和系统时间,我已经通过其他方式得到了答案。在这个问题中,除了理论之外,我有兴趣了解两个不同过程报告的时间的实际意义,实现相同的任务。
我有一个python程序和一个nodejs程序https://github.com/rnanwani/vips_performance。两者都处理一组输入图像并处理它们以获得不同的输出。两者都使用libvips实现。 这是两个
的时间的Python
真实 1m17.253s
用户 1m54.766s
sys 0m2.988s
NodeJS
真实 1m3.616s
用户 3m25.097s
sys 0m8.494s
实时(对于NodeJS,其他答案的挂钟时间较短,根据我的理解,这意味着从输入到输出的整个过程在NodeJS上完成得更快。但是用户和系统时间非常长与Python相比。同样使用htop实用程序,我发现NodeJS进程在整个过程中CPU使用率约为360%,最大限度地发挥了4个内核的作用。另一方面,Python的CPU使用率在250%到120%之间。整个过程。
我想了解一些事情
答案 0 :(得分:1)
更小的实时时间和更高的用户+系统时间是否意味着进程(在本例中为Node)更有效地利用CPU来更快地完成任务?
它并不一定意味着他们更有效地利用处理器。
较高的用户时间意味着Node正在利用更多的用户空间处理器时间,从而更快地完成任务。正如Luke Exton所说,cpu花费更多时间在"你编写的代码/可能会看到"
较高的 sys 时间意味着会发生更多的上下文切换,这从您的htop利用率数字开始是有意义的。这意味着调度程序(内核进程)在操作系统操作和用户空间操作之间跳转。这是找到CPU来安排任务的时间。
这些时代的实际意义是什么 - 随着请求数量的增加,更快/更好/会扩展得更好?
实施问题很长,并且有许多警告。我假设从python vs Node数字来看,Python线程更长,反过来做更多的内联处理。另外需要注意的是python中的GIL。基本上python是一个单线程应用程序,你不能轻易打破这个。这可能是Node实现更快(使用真实线程)的一个因素。 节点似乎被编写为正确的线程并将许多任务拆分出来。高线程应用程序的优点将有一个转折点,您将花费更多的时间来尝试为新线程找到一个免费的CPU,而不是实际工作。当发生这种情况时,你的python实现可能会再次开始变快。
答案 1 :(得分:1)
更高的用户+系统时间意味着该进程有更多正在运行的线程,并且您已经注意到,通过查看360%使用了4核的几乎所有可用CPU资源。这意味着NodeJS进程已经受到可用CPU资源的限制,无法处理更多请求。此外,您最终可以在该计算机上运行的任何其他CPU密集型进程都将进入您的NodeJS进程。另一方面,Python进程并不占用所有可用的CPU资源,并且可能会随着大量请求而扩展。
答案 2 :(得分:1)
我的猜测是节点一次运行多个vips管道,而python严格依次运行。管道启动和关闭主要是单线程的,因此如果node一次启动多个管道,它可能会节省一些时间,正如您所观察到的那样。
您可以在随机访问模式下加载JPEG图像,因此整个图像将使用libjpeg解压缩到内存中。这是一个单线程库,所以你永远不会看到超过100%的CPU使用。
接下来,您调整大小/旋转/裁剪/ jpegsave。运行这些操作时,调整大小将很好地解决,CPU负载随着减少的平方而增加,旋转太简单而不会对运行时产生太大影响,并且裁剪是即时的。虽然jpegsave是单线程的(当然)vips在一个单独的后台线程中从后写缓冲区运行,所以你有效地免费获得它。
我在台式机上尝试了你的程序(六个超线程内核,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后写线程):
$ 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倍的加速。
基准测试很困难,而且/ real / user / sys很难解释。你需要考虑很多因素:
我确信很多其他人我已经忘记了。
如果您有点好奇,libvips拥有它自己的探查器,可以帮助您更深入地了解运行时行为。它可以显示各种工作线程的图形,它们在同步中花费的时间,内务处理的时间,实际处理像素的时间,分配内存的时间以及最终再次释放的时间。这里有关于它的博客文章:
http://libvips.blogspot.co.uk/2013/11/profiling-libvips.html
答案 3 :(得分:0)
所以这些时间本身并不可靠,他们说这个过程需要多长时间才能对CPU执行操作。这与在该机器上同时发生的任何其他事件紧密耦合,并且可能完全基于物理资源而大幅波动。
具体而言:
具体来说,小实时意味着它实际上完成得更快。这是否意味着它确实做得更好,不。例如,同时机器上可能发生的事情较少。
就规模而言,这些数字有点无关紧要,它取决于架构/瓶颈。例如,就规模而言,特别是云计算,它是关于为每个(通常是计算,磁盘,网络)有效地分配资源和相关IO。是否尽快处理此图像有助于扩展?也许?您需要检查瓶颈和细节以确定。例如,在您达到计算限制之前,它可能会压倒您的网络链接,然后您就会受到限制。或者您可能会受到写入磁盘的速度的限制。
答案 4 :(得分:0)
其中一个潜在的重要方面是没有人提及你的库(vips)本身会启动线程的事实: http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/using-threads.html
当libvips计算图像时,默认情况下会使用尽可能多的图像 线程,因为你有CPU核心。使用vips_concurrency_set()进行更改 此
这解释了最让我感到惊讶的事情 - NodeJS应该(据我的理解)是非常单线程的,就像Python的GIL一样。它完全是关于异步处理和所有。 因此,对于vips的Python和Node绑定可能只使用不同的线程设置。这值得研究。
(也就是说,快速查看没有发现任何一个库中默认并发级别发生变化的证据)