我有一个非常好的perl子例程,作为perl模块的一部分编写。没有太多细节,它需要一个字符串和一个短列表作为参数(通常从终端获取)并吐出一个值(现在,总是一个浮点,但情况可能并非总是如此。)
现在,我的参数的列表部分有两个值,比如说(val1,val2)。我使用for循环为val1和val2保存了我的子程序的输出数百个不同的值。每次迭代都需要几秒钟才能完成 - 因此完成整个过程需要数小时。
我最近读过一个名为“线程”的神秘(对我来说)计算工具,它显然可以替代具有超快执行时间的循环。我一直无法理解这些是什么和做什么,但我认为它们与并行计算有关(我希望我的模块尽可能优化并行处理器。)
如果我保存所有要传递给val1的值作为列表,比如@ val1和val2相同,我如何使用这些“线程”为val1的每个元素组合执行我的子程序VAL2? 此外,知道如何将此过程推广到也使用val3,val4等的子例程将会很有帮助。
答案 0 :(得分:6)
我不使用PDL所以我不知道PDL中的线程与我一直在讨论的线程概念完全不一致。见PDL threading and signatures:
首先,我们必须解释PDL背景下线程化的含义,特别是因为术语线程已经在计算机科学中具有明显的含义,只是部分地与PDL中的使用一致。
但是,我认为下面的解释对您仍然有用,因为需要知道常规意义上的线程是如何理解PDL线程的不同之处。
以下是背景的Threads entry on Wikipedia。
使用线程无法让您的程序神奇地加快速度。 如果你有多个CPU /核心,如果你正在执行的计算可以分成独立的块,使用线程可以允许你的程序在一个以上的计算中携带多个计算时间和减少总执行时间。
最简单的情况是当子任务embarrassingly parallel不需要线程之间的通信/协调时。
关于可能的性能提升,请考虑以下程序:
#!/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 : Elapsed Time : 00:00:02.375
C:\> timethis t.pl 2 TimeThis : Elapsed Time : 00:00:02.515
C:\> timethis t.pl 3 TimeThis : Elapsed Time : 00:00:03.734
C:\> timethis t.pl 4 TimeThis : Elapsed Time : 00:00:04.703
...
C:\> timethis t.pl 10 TimeThis : Elapsed Time : 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 : Elapsed Time : 00:00:22.312