У меня есть пример последовательности ДНК, такой как: S = ATGCGGGCGTGCTGCTGGGCTGCT....
длиной 5 МБ. Кроме того, у меня есть координаты гена для каждого гена, например:
Gene no. Start End
1 1 50
2 60 100
3 110 250
.....
4000 4640942 4641628
Моя цель — выполнить определенный расчет для каждой стартовой позиции гена. Мой код работает отлично. Однако это довольно медленно. Я просмотрел много справочных страниц, чтобы ускорить работу с помощью потоков, но, к сожалению, не смог понять.
Вот краткое изложение моего кода:
foreach my $gene($sequence){
my @coordinates = split("\t",$gene);
$model1 = substr($sequence, $coordinates[1], 50);
$model2 = substr($sequence, $coordinates[1], 60);
$c-value = calculate($model1, $model2);
....
}
sub calculate {
......
}
Я был бы очень признателен, если бы кто-нибудь мог предложить мне, как распараллелить такие программы. Что я хочу распараллелить, так это вычисление c-value между model1 и model2 для каждого гена, что в итоге ускорит процесс. Я пытался использовать Threads::queue, но закончился кучей ошибок. Я новичок в программировании на Perl, поэтому любая помощь приветствуется.
Спасибо всем за комментарии и предложения. Я изменил код, и, похоже, он работает с использованием Perl-модуля Parallel::ForkManager. Код успешно использует все 4 ядра моего компьютера.
Вот измененный код:
use strict;
use warnings;
use Data::Dumper;
use Parallel::ForkManager;
my $threads = 4;
my $pm = new Parallel::ForkManager($threads);
my $i = 1; #gene number counter
$pm -> run_on_finish( sub { $i++; print STDERR "Checked $i genes" if ($i % $number_of_genes == 0); } );
my @store_c_value = ();
foreach my $gene($sequence){
my $pid = $pm->start and next;
my @coordinates = split("\t",$gene);
my $model1 = substr($sequence, $coordinates[1], 50);
my $model2 = substr($sequence, $coordinates[1], 60);
my $c-value = calculate($model1, $model2);
push(@store_c_value, $c-value);
$i++;
$pm->finish;
}
$pm->wait_all_children;
sub calculate {
......
return ($c-value);
}
print Dumper \@store_c_value;
Текущая проблема заключается в том, что я не получаю никакого вывода для @store_c_value
(т.е. пустой массив). Я обнаружил, что вы не можете сохранить данные из дочернего процесса в массив, который был объявлен в основной программе. Я знаю, что могу распечатать его во внешний файл, но я хочу, чтобы эти данные были в массиве @store_c_value
, так как я буду использовать его позже в программе.
Еще раз спасибо за помощь.
AnyEvent::Fork
metacpan.org/pod/AnyEvent::Fork. - person UjinT34   schedule 28.10.2018$c-value
не является допустимым идентификатором Perl. Если вы используете строгие и предупреждения (вы должны), это вызовет ошибку из-за значения bareword. В идентификаторах Perl допустимы только символы слова (буквы, цифры, знак подчеркивания). - person Grinnz   schedule 28.10.2018foreach my $gene($sequence){
не имеет смысла, он будет выполняться только один раз, потому что вы указали одно скалярное значение для его повторения. - person Grinnz   schedule 28.10.2018Parallel::ForkManager
, см. в этой публикации (и ссылке в ней, и связанной документации). - person zdim   schedule 29.10.2018