首页 文章

如何使用线程替换在perl / pdl中循环子例程

提问于
浏览
2

我有一个非常好的perl子例程,作为perl模块的一部分编写 . 没有太多细节,它需要一个字符串和一个短列表作为参数(通常从终端获取)并吐出一个值(现在,总是一个浮点,但情况可能并非总是如此 . )

现在,我的参数的列表部分有两个值,比如说(val1,val2) . 我使用for循环为val1和val2保存了我的子程序的输出数百个不同的值 . 每次迭代都需要几秒钟才能完成 - 因此完成整个过程需要数小时 .

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

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

1 回答

  • 6

    更新:

    我不使用PDL所以我不知道PDL中的线程与我一直在讨论的线程概念完全不对应 . 见PDL threading and signatures

    首先,我们必须解释PDL背景下线程的含义,特别是因为术语线程已经在计算机科学中具有明显的含义,只是部分地与其在PDL中的使用一致 .

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

    这是背景的Threads entry on Wikipedia .

    使用线程无法使您的程序神奇地更快 . If 您有多个CPU /核心 if 您正在执行的计算可以分为独立的块,使用线程可以允许您的程序一次携带多个计算并减少总执行时间 .

    最简单的情况是当子任务是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
    

相关问题