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个人