我有一个perl程序,试图将一堆文件从一种格式转换为另一种格式(通过命令行工具)。它工作正常,但速度太慢,因为它一次转换文件。perl fork()似乎没有利用核心,但只有cpu
我研究并利用了fork()机制,试图产生所有希望利用cpu/cores的子fork的转换。
编码完成并测试,它确实提高了性能,但不符合我的预期。 当的/ proc/cpuinfo中寻找,我有这样的:
> egrep -e "core id" -e ^physical /proc/cpuinfo|xargs -l2 echo|sort -u
physical id : 0 core id : 0
physical id : 0 core id : 1
physical id : 0 core id : 2
physical id : 0 core id : 3
physical id : 1 core id : 0
physical id : 1 core id : 1
physical id : 1 core id : 2
physical id : 1 core id : 3
这意味着我有2个CPU和四核的每一个?如果是这样,我应该能够分出8个分支,假设我应该能够在1分钟内完成8分钟的工作(每个文件1分钟,8个文件)以完成(8个分叉,每个分叉1个文件)。
但是,当我测试运行这个,它仍然需要4分钟才能完成。看起来它只用了2个CPU,而不是内核?
因此,我的问题是:
这是真的,Perl的fork()的唯一平行它的基础上的CPU,但不是核心?或者,也许我没有做对吗?我只是使用fork()和wait()。没什么特别的。我会假设perl的fork()应该使用核心,是否有一个简单的bash/perl,我可以写来证明我的操作系统(即RedHat 4),Perl也不是这种症状的罪魁祸首?
补充:
我甚至尝试运行以下命令多次模拟多个处理和监控HTOP。
while true; do echo abc >>devnull; done &
不知何故htop告诉我我有16个内核?然后当我产生4个以上的while循环时,我看到其中4个使用〜100%cpu。当我产生更多的时候,他们都开始平均降低CPU利用率。 (例如8次处理,请参阅htop中的8 bash,但每次使用约50%)这是否意味着什么?
提前感谢。我试过谷歌周围,但无法找到明显的答案。
编辑:2016年11月9日
这里是Perl代码的提取物。我很想看看我在这里做错了什么。
my $maxForks = 50;
my $forks = 0;
while(<CIFLIST>) {
extractPDFByCIF($cifNumFromIndex, $acctTypeFromIndex, $startDate, $endDate);
}
for (1 .. $forks) {
my $pid = wait();
print "Child fork exited. PID=$pid\n";
}
sub extractPDFByCIF {
# doing SQL constructing to for the $stmt to do a DB query
$stmt->execute();
while ($stmt->fetch()) {
# fork the copy/afp2web process into child process
if ($forks >= $maxForks) {
my $pid = wait();
print "PARENTFORK: Child fork exited. PID=$pid\n";
$forks--;
}
my $pid = fork;
if (not defined $pid) {
warn "PARENTFORK: Could not fork. Do it sequentially with parent thread\n";
}
if ($pid) {
$forks++;
print "PARENTFORK: Spawned child fork number $forks. PID=$pid\n";
}else {
print "CHILDFORK: Processing child fork. PID=$$\n";
# prevent child fork to destroy dbh from parent thread
$dbh->{InactiveDestroy} = 1;
undef $dbh;
# perform the conversion as usual
if($fileName =~ m/.afp/){
system("file-conversion -parameter-list");
} elsif($fileName =~ m/.pdf/) {
system("cp $from-file $to-file");
} else {
print ERRORLOG "Problem happened here\r\n";
}
exit;
}
# end forking
$stmt->finish();
close(INDEX);
}
Perl只是使用'fork'系统调用。你应该在C中看到完全相同的行为。 – ikegami
没有看到代码就很难调试。 – shawnhcorey
您的代码可能有问题;显示它,我们可以提供帮助。 – ysth