线程/分叉的效率

时间:2013-04-30 02:09:00

标签: multithreading perl parallel-processing fork

所以,我正在考虑使用分叉或线程来做一些简单的parralelization。为了确保它值得,我编写了三个简单的脚本来对顺序与线程和分叉进行基准测试。我使用了两个非常简单的方法来初始化一个数组数组,然后使用另一个方法来查找每个数组中的max元素并将其写入文件。

方法:

sub initialize
{
    for (my $i=0; $i <= 2; $i++)
    {
        for (my $j=0; $j < 5000000; $j++)
        {
        $array[$i][$j]=$j+$i;
        }
    }
}  

sub getMax 
{
        my $num = shift;
        my $array = shift;
        my $length=scalar(@{$array});
        my $max=-9**9**9;
        my @ra;

        for (my $i=0; $i < $length; $i++) 
        {
            if ($max < ${$array}[$i])
            {
            $max=${$array}[$i];
            }
        }

        tie @ra, 'Tie::File', "test.txt" or die;
        $ra[$num]=$max;
}

依序:

my $start = Time::HiRes::time();
for (my $count = 0; $count <= 2; $count++) 
{
    getMax($count,$array[$count]);
}

my $stop = Time::HiRes::time();
my $duration = $stop-$start;
print "Time spent: $duration\n"; 
print "End of main program\n";

线程:

my @threads=();
my $start = Time::HiRes::time();
for (my $count = 0; $count <= 2; $count++) 
{
    my $t = threads->new(\&getMax, $count, $array[$count]);
    push(@threads,$t);
}

foreach (@threads) 
{
    my $num = $_->join;
}

my $stop = Time::HiRes::time();
my $duration = $stop-$start;
print "Time spent: $duration\n";
print "End of main program\n";

分岔:

my $pm = Parallel::ForkManager->new(3);
my $start = Time::HiRes::time();

for (my $count = 0; $count <= 2; $count++)
{
    my $pid = $pm->start and next;   
    getMax($count,$array[$count]);
    $pm->finish; 
}

$pm->wait_all_children;

my $stop = Time::HiRes::time();
my $duration = $stop-$start;

print "Time spent: $duration\n";
print "\nEnd of main program\n";

顺序:2.88秒

线程:4.10秒

分叉:3.88秒

我想这是出于我的目的(显然不是这个,但是计算密集程度不是太大),线程/分叉没有帮助。我知道这两者并不仅仅用于时间效率,但我认为这取决于你正在做什么的好处之一。所以,我的问题是,线程/分叉究竟何时实际上使代码运行得更快?

1 个答案:

答案 0 :(得分:4)

处理器和内存是计算机中最快的组件。由于快速内存也很昂贵,因此磁盘驱动器用于以低成本方式存储大量数据,而需要权衡它访问速度要慢得多。

当计算机程序依赖于来自慢速媒体的数据时,在必要的数据到达之前,通常可以使更快的组件无事可做。多线程的主要用途是允许处理器在等待所需资源的同时继续使用其他东西。

可以并行完成的各种事情是

  • 在等待某事完成时保持用户界面正常运行

  • 进行多处理器计算

  • 从多个网站获取数据

  • 从多个磁盘驱动器读取

关于所有这些的重要之处在于,如果线程不相互竞争相同的资源,则多线程才有利。

例如,尝试通过读取两个线程中的每个线程中的一半数据来加速磁盘读取将成功,因为磁盘控制器存在瓶颈并限制如何它可以快速返回数据。但RAID驱动器可以通过同时从多个驱动器中读取部分数据来加快速度。

在您的示例中,只有一个处理器可以执行最大计算。获得多个线程并不意味着处理器可以更快地完成工作,实际上它必须通过在线程之间切换来减慢速度。但是,如果您可以安排在多处理器系统的单独处理器上运行每个线程,那么获得优势。视听软件经常使用这种技术来获得最大的处理速度。

同样,从多个互联网源并行获取数据非常有用,但只有在达到链接容量之后,线程才会开始相互竞争带宽。