Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 并行ForkManager,DBI。比分叉前快,但还是太慢_Performance_Perl_Dbi_Fork - Fatal编程技术网

Performance 并行ForkManager,DBI。比分叉前快,但还是太慢

Performance 并行ForkManager,DBI。比分叉前快,但还是太慢,performance,perl,dbi,fork,Performance,Perl,Dbi,Fork,我有一个关于更新数据库的非常简单的任务 my $pm = new Parallel::ForkManager(15); for my $line (@lines){ my $pid = $pm->start and next; my $dbh2 = $dbh->clone(); my $sth2 = $dbh2->prepare("update db1 set field1=? where field2 =?"); my (

我有一个关于更新数据库的非常简单的任务

my $pm = new Parallel::ForkManager(15);
for my $line (@lines){
    my $pid = $pm->start and next;
    my $dbh2 = $dbh->clone();
    my $sth2 = $dbh2->prepare("update db1 set field1=? where field2 =?");           
    my ($field1, $field2) = very_slow_subroutine();
    $sth2->execute($field1,$field2);
    $pm->finish;        
} 
 $pm->wait_all_children;    
我可以只使用$dbh2->do,但我怀疑这是速度缓慢的原因

有趣的是,这15个过程(或我指定的任何过程)似乎启动得非常快,但之后速度急剧下降,仍然明显快于没有分叉,但我会期待更多

编辑:

非常慢的子例程是sub,它从web服务获取答案。服务可以在超时时从几秒钟到几秒钟进行应答。我不得不问上好几千次。。。我想做叉子的原因


如果这很重要的话——我在Linux上

并行性是否有帮助取决于瓶颈在哪里。如果您的CPU有4个内核是瓶颈,那么在最佳情况下,分叉4个进程可能会使事情在大约1/4的时间内完成,但是生成15个进程并不能改善更多

如果更可能的情况是,您的瓶颈在I/O中,那么启动15个争用同一I/O的进程不会有多大帮助,尽管在有大量内存可用作文件缓存的情况下,这是可能的

探讨系统的限制,考虑以下程序:

#!/usr/bin/env perl

use strict;
use warnings;

use Parallel::ForkManager;

run(@ARGV);

sub run {
    my $count = @_ ? $_[0] : 2;
    my $pm = Parallel::ForkManager->new($count);
    for (1 .. 20) {
        $pm->start and next;
        sleep 1;
        $pm->finish;
    }
    $pm->wait_all_children;
}
我的老式笔记本电脑只有一个CPU和两个内核。让我们看看我得到了什么:

TimeThis : Command Line : perl sleeper.pl 1 TimeThis : Elapsed Time : 00:00:20.735 TimeThis : Command Line : perl sleeper.pl 2 TimeThis : Elapsed Time : 00:00:06.578 TimeThis : Command Line : perl sleeper.pl 4 TimeThis : Elapsed Time : 00:00:04.578 TimeThis : Command Line : perl sleeper.pl 8 TimeThis : Elapsed Time : 00:00:03.546 TimeThis : Command Line : perl sleeper.pl 16 TimeThis : Elapsed Time : 00:00:02.562 TimeThis : Command Line : perl sleeper.pl 20 TimeThis : Elapsed Time : 00:00:02.563 TimeThis:命令行:perl sleeper.pl 1 时间此:经过的时间:00:00:20.735 TimeThis:命令行:perl sleeper.pl 2 时间此:经过的时间:00:00:06.578 TimeThis:命令行:perl sleeper.pl 4 时间此:经过的时间:00:00:04.578 TimeThis:命令行:perl sleeper.pl 8 时间此:经过的时间:00:00:03.546 TimeThis:命令行:perl sleeper.pl 16 时间此:经过的时间:00:00:02.562 TimeThis:命令行:perl sleeper.pl 20 时间此:经过的时间:00:00:02.563 因此,使用最多20个进程运行,一秒钟睡眠20次的总运行时间超过2.5秒

另一方面,只需一个过程,睡眠一秒20次只需20秒。这是一个巨大的改进,但它也表明,当您有20个进程每一秒都处于休眠状态时,管理开销将超过150%


这是并行编程的本质。对于你能期望的东西,有很多正式的处理方法,但都是必读的。

并行性是否有帮助取决于你的瓶颈在哪里。如果您的CPU有4个内核是瓶颈,那么在最佳情况下,分叉4个进程可能会使事情在大约1/4的时间内完成,但是生成15个进程并不能改善更多

如果更可能的情况是,您的瓶颈在I/O中,那么启动15个争用同一I/O的进程不会有多大帮助,尽管在有大量内存可用作文件缓存的情况下,这是可能的

探讨系统的限制,考虑以下程序:

#!/usr/bin/env perl

use strict;
use warnings;

use Parallel::ForkManager;

run(@ARGV);

sub run {
    my $count = @_ ? $_[0] : 2;
    my $pm = Parallel::ForkManager->new($count);
    for (1 .. 20) {
        $pm->start and next;
        sleep 1;
        $pm->finish;
    }
    $pm->wait_all_children;
}
我的老式笔记本电脑只有一个CPU和两个内核。让我们看看我得到了什么:

TimeThis : Command Line : perl sleeper.pl 1 TimeThis : Elapsed Time : 00:00:20.735 TimeThis : Command Line : perl sleeper.pl 2 TimeThis : Elapsed Time : 00:00:06.578 TimeThis : Command Line : perl sleeper.pl 4 TimeThis : Elapsed Time : 00:00:04.578 TimeThis : Command Line : perl sleeper.pl 8 TimeThis : Elapsed Time : 00:00:03.546 TimeThis : Command Line : perl sleeper.pl 16 TimeThis : Elapsed Time : 00:00:02.562 TimeThis : Command Line : perl sleeper.pl 20 TimeThis : Elapsed Time : 00:00:02.563 TimeThis:命令行:perl sleeper.pl 1 时间此:经过的时间:00:00:20.735 TimeThis:命令行:perl sleeper.pl 2 时间此:经过的时间:00:00:06.578 TimeThis:命令行:perl sleeper.pl 4 时间此:经过的时间:00:00:04.578 TimeThis:命令行:perl sleeper.pl 8 时间此:经过的时间:00:00:03.546 TimeThis:命令行:perl sleeper.pl 16 时间此:经过的时间:00:00:02.562 TimeThis:命令行:perl sleeper.pl 20 时间此:经过的时间:00:00:02.563 因此,使用最多20个进程运行,一秒钟睡眠20次的总运行时间超过2.5秒

另一方面,只需一个过程,睡眠一秒20次只需20秒。这是一个巨大的改进,但它也表明,当您有20个进程每一秒都处于休眠状态时,管理开销将超过150%


这是并行编程的本质。对于您可以期望的内容,有很多正式的处理方法,但都是必读的。

Parallel::ForkManager并没有神奇地让事情变得更快,它只是让您在同一时间多次运行代码。为了从中获益,您必须为并行性设计代码

这样想吧。你需要10分钟才能到达商店、购物、装车、回来、卸货。你需要得到5个负载。只有你一个人能在50分钟内完成。这是连续工作。10分钟*5次行程一次接一次=50分钟

假设你有四个朋友帮忙。你们都同时出发去商店。还有5次旅行,仍然需要10分钟,但是因为你是并行的,所以总时间只有10分钟

但无论你要去多少次旅行,或者你要帮助多少朋友,都不会少于10分钟。这就是为什么这个过程启动得很快,每个人都进入自己的汽车,开车去商店,但随后一段时间什么也没有发生,因为每个人完成工作仍然需要10分钟

这里也一样。你的环体跑起来需要X个时间。如果你对它进行Y次迭代,它将需要X*Y真实世界的人类时间来运行。如果您以并行的Y时间运行它,理想情况下只需X时间即可运行。每个并行工作程序仍必须执行循环的整个主体,时间为X

为了进一步加快速度,您必须打破
非常慢的子例程的大瓶颈,并使其并行工作。您的SQL非常简单,因此您应该将精力集中在优化和并行上

假设商店离我们很近,只需1分钟的车程(这是您的SQL更新),但是购物、加载和卸载需要9分钟(这是
非常慢的子例程)。如果你有5辆车和15个朋友呢。你载了3个人