Как я могу заставить свой сценарий Perl использовать несколько ядер для дочерних процессов?

Я работаю над математической моделью, которая использует данные, сгенерированные от XFOIL, популярный аэрокосмический инструмент раньше находил лифт и коэффициенты лобового сопротивления на крыльях.

У меня есть сценарий Perl, который неоднократно называет XFOIL с различными входными параметрами для генерации данных, в которых я нуждаюсь. Мне нужен XFOIL для выполнения 5,600 раз, приблизительно в 100 секунд на выполнение, дни soabout 6.5 для завершения.

У меня есть четырехъядерная машина, но мой опыт как программист ограничен, и я действительно только знаю, как использовать основной Perl.

Я хотел бы выполнить четыре экземпляра XFOIL за один раз, всех на их собственном ядре. Что-то вроде этого:

while ( 1 ) {

    for ( i = 1..4 ) {

        if ( ! exists XFOIL_instance(i) ) {

            start_new_XFOIL_instance(i, input_parameter_list);
        }
    }
} 

Таким образом, программа проверяет (или предпочтительно спит), пока экземпляр XFOIL не свободен, когда мы можем запустить новый экземпляр с нового списка входных параметров.

15
задан Borodin 19 April 2018 в 17:46
поделиться

2 ответа

Try Parallel::ForkManager. Это модуль, который предоставляет простой интерфейс для отключения таких процессов.

Вот пример кода:

#!/usr/bin/perl

use strict;
use warnings;
use Parallel::ForkManager;

my @input_parameter_list = 
    map { join '_', ('param', $_) }
    ( 1 .. 15 );

my $n_processes = 4;
my $pm = Parallel::ForkManager->new( $n_processes );
for my $i ( 1 .. $n_processes ) {
    $pm->start and next;

    my $count = 0;
    foreach my $param_set (@input_parameter_list) {         
        $count++;
        if ( ( $count % $i ) == 0 ) {
            if ( !output_exists($param_set) ) {
                start_new_XFOIL_instance($param_set);
            }
        }
    }

    $pm->finish;
}
$pm->wait_all_children;

sub output_exists {
    my $param_set = shift;
    return ( -f "$param_set.out" );
}

sub start_new_XFOIL_instance {
    my $param_set = shift;
    print "starting XFOIL instance with parameters $param_set!\n";
    sleep( 5 );
    touch( "$param_set.out" );
    print "finished run with parameters $param_set!\n";
}

sub touch {
    my $fn = shift;
    open FILE, ">$fn" or die $!;
    close FILE or die $!;
}

Вам нужно будет предоставить собственные реализации для функции start_new_XFOIL_instance и функции output_exists, а также определить собственные наборы параметров для передачи в XFOIL.

17
ответ дан 1 December 2019 в 02:55
поделиться

Похоже, что для этого проекта можно использовать gearman.

www.gearman.org

Gearman - это очередь заданий. Я бы порекомендовал использовать сайт amazon.com или даже их аукционные серверы для завершения этого проекта.

Потратив 10 центов за вычислительный час или меньше, вы можете значительно ускорить работу над проектом.

Я бы использовал gearman локально, убедитесь, что у вас есть "идеальный" прогон для 5-10 ваших субъектов, прежде чем передавать его на вычислительную ферму amazon.

.
4
ответ дан 1 December 2019 в 02:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: