Как использовать потоки для замены цикла подпрограммы в perl / pdl

У меня есть отличная подпрограмма на Perl, написанная как часть модуля Perl. Не вдаваясь в подробности, он принимает в качестве аргументов строку и короткий список (часто берется из терминала) и выдает значение (сейчас всегда с плавающей запятой, но это может быть не всегда).

Прямо сейчас часть моего аргумента, содержащая список, принимает два значения, скажем (val1, val2). Я сохраняю вывод моей подпрограммы для сотен различных значений для val1 и val2, используя циклы for. Каждая итерация занимает почти секунду, поэтому на выполнение всего процесса уходит часы.

Недавно я прочитал о мистическом (для меня) вычислительном инструменте под названием «threading», который, по-видимому, может заменить циклы for с невероятно быстрым временем выполнения. У меня возникли проблемы с пониманием того, что это такое и что они делают, но я полагаю, что они имеют какое-то отношение к параллельным вычислениям (и я хотел бы, чтобы мой модуль был как можно более оптимизирован для параллельных процессоров).

Если я сохраню все значения, которые хочу передать val1 в виде списка, скажем @ val1 и то же самое для val2, как я могу использовать эти «потоки» для выполнения моей подпрограммы для каждой комбинации элементов val1 и val2? Кроме того, было бы полезно знать, как обобщить эту процедуру на подпрограмму, которая также принимает значения val3, val4 и т. Д.


person Feynman    schedule 07.09.2010    source источник
comment
потоки perldoc.   -  person Ether    schedule 08.09.2010
comment
Да, я смотрел на это, но боюсь, что все еще не понимаю. My $ thr = thread- ›create (sub {...}, ...); кажется, это то, что я ищу, но я не понимаю, как его использовать. Я просмотрел руководства и еще много чего, но все еще не понимаю, как реализовать потоки. Например: мой $ thr = thread- ›create (sub {...}, ...); создать подпрограмму, которая действует точно так же, как обычная, но выполняется параллельно? Это было бы моим предположением, но мне особо не о чем говорить.   -  person Feynman    schedule 08.09.2010
comment
нет, он запускает поток, выполняющий эту подпрограмму, и возвращает объект потока, точно так, как говорит perldoc.   -  person hobbs    schedule 08.09.2010


Ответы (1)


Обновлять:

Я не использую PDL, поэтому я не знал, что поток в PDL не совсем соответствует понятию потоковой передачи, о котором я говорил. См. потоки PDL и подписи:

Сначала мы должны объяснить, что мы подразумеваем под потоковой передачей в контексте PDL, тем более что термин многопоточность уже имеет особое значение в информатике, которое лишь частично согласуется с его использованием в PDL.

Однако я думаю, что приведенное ниже объяснение по-прежнему полезно для вас, поскольку нужно знать, что такое потоки в обычном смысле, чтобы понять, чем отличаются потоки PDL.

Вот справочная информация Темы в Википедии.

Использование потоков не может волшебным образом сделать вашу программу быстрее. Если у вас несколько процессоров / ядер и если выполняемые вами вычисления можно разделить на независимые фрагменты, использование потоков может позволить вашей программе выполнять более одного вычисления за один время и сократить общее время выполнения.

Самый простой случай - это когда подзадачи поразительно параллельны, не требуя связи / координации между потоками.

Что касается возможного увеличения производительности, рассмотрите следующую программу:

#!/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
person Sinan Ünür    schedule 08.09.2010
comment
да! Это то, что я ищу! В настоящее время я использую не более одного процессора, но у меня есть доступ к большему количеству. Итак, чтобы эта технология потоковой передачи работала, мне НЕОБХОДИМО иметь более одного процессора? PDL придавал большое значение тому, что это намного эффективнее по времени, чем для циклов. Ничего не сказано о количестве процессоров. - person Feynman; 08.09.2010
comment
Если один или несколько потоков тратят много времени на блокировку ввода-вывода, использование потоков также может улучшить общее время выполнения, но я недостаточно знаю специфику вашей проблемы, чтобы иметь возможность комментировать ее. В конечном итоге, если у вас один процессор / ядро, только одна программа может работать в течение любого заданного отрезка времени. - person Sinan Ünür; 08.09.2010