【问题标题】:How to speed up Parallel::ForkManager in perl如何在 perl 中加速 Parallel::ForkManager
【发布时间】:2018-02-16 09:01:01
【问题描述】:

我正在使用 EC2 亚马逊服务器执行 63 个文件的数据处理, 我正在使用的服务器有 16 个核心,但使用 perl Parallel::ForkManager 线程数 = 核心数,然后似乎有一半的核心正在休眠,工作核心不是 100% 并且在 25%~50% 左右波动 我还检查了 IO,它大多是空闲的。

use Sys::Info;
use Sys::Info::Constants qw( :device_cpu );
my $info = Sys::Info->new;
my $cpu  = $info->device( CPU => %options );

use Parallel::ForkManager;
my $manager=new Parallel::ForkManager($cpu->count);

for($i=0;$i<=$#files_l;$i++)
{
        $manager->start and next;
        do_stuff($files_l[$i]);
        $manager->finish;
} 
$manager->wait_all_children;

【问题讨论】:

  • 拨打do_stuff大概需要多长时间?
  • 如果将$cpu-&gt;count 替换为0,CPU 有多忙?
  • $cpu-&gt;count 是否与您通过查看 /proc/cpuinfo 所期望的相符?
  • 你将什么%options 传递给Sys::Info

标签: multithreading perl


【解决方案1】:

简短的回答是 - 我们不能告诉你,因为这完全取决于“do_stuff”在做什么。

并行代码不会产生线性速度增加的主要原因是:

  • 进程创建开销 - 为生成进程执行了一些“工作”,因此如果子进程非常小,则会“浪费”努力。
  • 满足的资源 - 最常见的是磁盘 IO,但文件锁、数据库句柄、套接字或进程间通信等也可以发挥作用。
  • 导致进程停止的“退避”的其他原因。

在不知道“do_stuff”做什么的情况下,我们无法猜测它可能是什么。

不过我会建议几个步骤:

  • 将进程数加倍至 CPU 计数的两倍。这通常是一个“甜蜜点”,因为这意味着进程中的任何非 CPU 延迟都意味着其他进程中的一个可以全速运行。
  • 试试strace -fTt &lt;yourprogram&gt;(如果您使用的是 linux,则其他 Unix 变体上的命令会略有不同)。然后使用strace -fTtc 再次执行此操作,因为c 将汇总系统调用运行时间。看看哪些花费最多的“时间”。
  • 分析您的代码以查看热点在哪里。 Devel::NYTProf 是您可以使用的一个库。

还有几个小问题:

my $manager=new Parallel::ForkManager($cpu->count);

最好写成:

my $manager=Parallel::ForkManager -> new ( $cpu->count);

而不是使用间接对象表示法。

如果您只是在迭代 @files,那么最好不要使用循环计数变量,而是:

foreach my $file ( @files ) { 
    $manager -> start and next;
    do_stuff($file);
    $manager -> finish;
}

【讨论】:

  • 抱歉,回复晚了,我完成了“do stuff”的执行并得到了结果,经过更多关注后,似乎减速与我在“do stuff”中调用的命令有关使用压缩文件而不是并行框架。
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-17
相关资源
最近更新 更多