2

我有一个非常好的 perl 子例程,作为 perl 模块的一部分编写。在不涉及太多细节的情况下,它将一个字符串和一个简短列表作为参数(通常取自终端)并输出一个值(现在,总是一个浮点数,但可能并非总是如此。)

现在,我的论点的列表部分采用两个值,例如 (val1,val2)。我使用 for 循环将子例程的输出保存为 val1 和 val2 的数百个不同值。每次迭代几乎需要一秒钟才能完成——因此完成整个过程需要几个小时。

我最近读到了一个神秘的(对我而言)名为“线程”的计算工具,它显然可以用极快的执行时间代替 for 循环。我一直无法理解这些是什么和做什么,但我想它们与并行计算有关(我希望我的模块尽可能针对并行处理器进行优化。)

如果我将要传递给 val1 的所有值保存为一个列表,比如 @val1 和 val2 相同,我如何使用这些“线程”为 val1 和 val2 的元素的每个组合执行我的子例程?此外,了解如何将此过程推广到也采用 val3、val4 等的子例程会很有帮助。

4

1 回答 1

6

更新:

我不使用 PDL,所以我不知道 PDL 中的线程与我一直在谈论的线程概念不完全对应。请参阅PDL 线程和签名

首先,我们必须解释在 PDL 上下文中线程的含义,特别是因为线程一词在计算机科学中已经具有独特的含义,仅部分同意它在 PDL 中的用法。

但是,我认为下面的解释对您仍然有用,因为需要知道常规意义上的线程是什么,才能理解 PDL 线程的不同之处。

这是Wikipedia 上的 Threads 条目作为背景。

使用线程不能让你的程序神奇地更快。如果您有多个 CPU/内核,并且正在执行的计算可以分成独立的块,则使用线程可以让您的程序一次执行多个计算并减少总执行时间。

最简单的情况是当子任务是令人尴尬的并行时,不需要线程之间的通信/协调。

关于可能的性能提升,请考虑以下程序:

#!/usr/bin/perl

use strict; use warnings;
use threads;

my ($n) = @ARGV;

my @threads = map { threads->create(\&act_busy) } 1 .. $n;

$_->join for @threads;

sub act_busy {
    for (1 .. 10_000_000) {
        my $x = 2 * 2;
    }
}

在我运行 Windows XP 的双核笔记本电脑上:

C:\> timethis t.pl 1
TimeThis:经过的时间:00:00:02.375
C:\> timethis t.pl 2
TimeThis:经过的时间:00:00:02.515
C:\> timethis t.pl 3
TimeThis:经过的时间:00:00:03.734
C:\> timethis t.pl 4
TimeThis:经过的时间:00:00:04.703
...
C:\> timethis t.pl 10
TimeThis:经过的时间:00:00:11.703

现在,将其与:

#!/usr/bin/perl

use strict; use warnings;

my ($n) = @ARGV;

act_busy() for 1 .. $n;

sub act_busy {
    for (1 .. 10_000_000) {
        my $x = 2 * 2;
    }
}
C:\> timethis s.pl 10
TimeThis:经过的时间:00:00:22.312
于 2010-09-08T00:15:28.660 回答