2009-12-25 28 views
15

Tôi là một sinh viên kỹ thuật hàng không vũ trụ, và tôi đang làm việc trên một dự án capstone cao cấp. Một trong những mô hình toán học mà tôi đang phát triển đòi hỏi một lượng dữ liệu thiên văn được tạo ra từ XFOIL, một công cụ hàng không vũ trụ phổ biến được sử dụng để tìm thang máy và hệ số kéo trên các cánh máy bay. (Nhưng tôi đang digressing.)Làm thế nào tôi có thể làm cho kịch bản Perl của tôi sử dụng nhiều lõi cho các tiến trình con?

Cắt theo đuổi: Tôi có một kịch bản Perl gọi XFOIL nhiều lần với các tham số đầu vào khác nhau để tạo dữ liệu tôi cần. Tôi cần XFOIL để chạy 5600 lần, và vì nó đứng ngay bây giờ nó mất khoảng 100 giây trung bình mỗi lần chạy. Làm toán, điều này có nghĩa là sẽ mất khoảng 6,5 ngày để hoàn thành.

Bây giờ, tôi có một máy quad-core, nhưng kinh nghiệm của tôi là một lập trình viên bị hạn chế, và tôi thực sự chỉ biết cách sử dụng Perl cơ bản. Tôi muốn chạy 4 phiên bản của XFOIL tại một thời điểm, tất cả trên lõi của chính họ. Một cái gì đó như thế này:

while (1){ 
    for (i = 1..4){ 
     if (! exists XFOIL_instance(i)){ 
      start_new_XFOIL_instance(i, input_parameter_list); 
     } 
    } 
} 

Vì vậy, các chương trình được kiểm tra (hoặc tốt hơn là ngủ cho đến khi một thể hiện XFOIL đánh thức nó dậy để bắt đầu một trường hợp mới) nếu mỗi lõi đang chạy XFOIL. Nếu không, ví dụ trước đó đã thoát và chúng ta có thể bắt đầu một cá thể mới với danh sách tham số đầu vào mới.

Nếu bất kỳ ai có bất kỳ ý tưởng nào về điều này có thể đạt được, vui lòng cho tôi biết. Điều này sẽ tăng tốc đáng kể thời gian tôi cần để tạo dữ liệu và sẽ cho phép tôi làm việc trên chính dự án hàng không vũ trụ.

Cảm ơn sự giúp đỡ!

+1

Tôi sợ tôi sẽ không cung cấp một câu trả lời đầy đủ, nhưng phiên bản ngắn là bạn chắc chắn có thể chia ra bốn trường hợp của kịch bản lệnh perl hiện tại, sau đó có mỗi lần liên tục xuất hiện để chạy tập lệnh XFOIL. Tuy nhiên, thiết lập ái lực bộ vi xử lý cho các quá trình kết quả - điều đó đòi hỏi phải biết bạn đang sử dụng hệ điều hành nào. –

+2

Bạn có chắc chắn XFOIL không phải là chủ đề hoặc sử dụng nhiều bộ xử lý để có thời gian chạy khoảng 100 giây ngay từ đầu không? – dlamblin

+0

Thật khó để triển khai XFOIL vào C/Fortran? Nếu không, sau đó tôi sẽ đề nghị bạn đi cho nó. Perl không chính xác là Gonzalez tốc độ của các ngôn ngữ lập trình ... – Zaid

Trả lời

17

Hãy thử Parallel::ForkManager. Đó là một mô-đun cung cấp một giao diện đơn giản để tắt các quy trình như thế này.

Dưới đây là một số mã ví dụ:

#!/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 $!; 
} 

Bạn sẽ cần phải cung cấp triển khai của riêng bạn cho start_new_XFOIL_instance và các chức năng output_exists, và bạn cũng sẽ muốn xác định bộ của riêng bạn của tham số để gửi XFOIL .

+1

Điều này có vẻ là những gì tôi cần. Tôi sẽ đọc lên trên Parallel :: ForkManager và cho bạn biết làm thế nào nó đi. Cảm ơn đã giúp đỡ! Tất nhiên, bất kỳ đầu vào nào khác từ bất kỳ ai được đánh giá cao. –

+0

Nếu bạn chưa biết, bạn có thể cài đặt mô-đun Parallel :: ForkManager trong thư mục chính của bạn. Hãy xem tại đây để biết cách thực hiện: http://stackoverflow.com/questions/540640/how-can-i-install-a-cpan-module-into-a-local-directory –

+1

James, cảm ơn rất nhiều vì Cứu giúp. Tôi đã cài đặt Parallel :: ForkManager qua dòng lệnh một chút trước đây - tôi nghĩ rằng tôi đang chạy và chạy ngay bây giờ. Tôi vẫn đang cố gắng tìm ra sự phức tạp của mô-đun cũng như cách tôi muốn nó hoạt động trong các điều kiện lỗi, nhưng một bước đầu tiên trên máy tính xách tay lõi kép của tôi khiến tôi nghĩ rằng tôi đã tìm ra điều này - ít nhất là ý tưởng cơ bản. Cảm ơn một lần nữa! –

3

Điều này có vẻ như bạn có thể sử dụng thiết bị cho dự án này.

www.gearman.org

Gearman là hàng đợi công việc. Bạn có thể chia dòng công việc của mình thành nhiều phần nhỏ.

Tôi khuyên bạn nên sử dụng amazon.com hoặc thậm chí máy chủ có thể đấu giá của họ để hoàn thành dự án này.

Chi tiêu 10cents cho mỗi giờ tính toán trở xuống, có thể tăng đáng kể dự án của bạn.

Tôi sẽ sử dụng gearman tại địa phương, đảm bảo rằng bạn chạy "hoàn hảo" cho 5-10 người đăng ký của bạn trước khi giao cho một trang trại tính toán amazon.

3

Perl threads sẽ tận dụng nhiều lõi và bộ xử lý. Chuyên nghiệp chính của chủ đề là khá dễ dàng để chia sẻ dữ liệu giữa các chủ đề và phối hợp các hoạt động của họ. Một quá trình chia hai không thể dễ dàng trả về dữ liệu cho phụ huynh hoặc không phối hợp với nhau.

Nhược điểm chính của chủ đề Perl là chúng tương đối đắt để tạo ra so với ngã ba, chúng phải sao chép toàn bộ chương trình và tất cả dữ liệu của chương trình; bạn phải biên dịch chúng thành Perl của bạn; và chúng có thể là lỗi, các Perl cũ hơn, các buggier các chủ đề. Nếu công việc của bạn đắt tiền, thời gian tạo ra không quan trọng.

Dưới đây là ví dụ về cách bạn có thể thực hiện với chuỗi. Có nhiều cách để làm điều đó, cái này sử dụng Thread::Queue để tạo danh sách công việc lớn mà chuỗi công nhân của bạn có thể chia sẻ. Khi hàng đợi trống, các luồng sẽ thoát. Những lợi thế chính là dễ dàng hơn để kiểm soát số lượng chủ đề đang hoạt động và bạn không phải tạo một chuỗi mới, đắt tiền cho mỗi bit công việc.

Ví dụ này đẩy tất cả công việc vào hàng đợi cùng một lúc, nhưng không có lý do gì bạn không thể thêm vào hàng đợi khi bạn đi. Nếu bạn đã làm điều đó, bạn sẽ sử dụng dequeue thay vì dequeue_nb sẽ đợi xung quanh để có thêm đầu vào.

use strict; 
use warnings; 

use threads; 
use Thread::Queue; 

# Dummy work routine 
sub start_XFOIL_instance { 
    my $arg = shift; 
    print "$arg\n"; 
    sleep 1; 
} 

# Read in dummy data 
my @xfoil_args = <DATA>; 
chomp @xfoil_args; 

# Create a queue to push work onto and the threads to pull work from 
# Populate it with all the data up front so threads can finish when 
# the queue is exhausted. Makes things simpler. 
# See https://rt.cpan.org/Ticket/Display.html?id=79733 
my $queue = Thread::Queue->new(@xfoil_args); 

# Create a bunch of threads to do the work 
my @threads; 
for(1..4) { 
    push @threads, threads->create(sub { 
     # Pull work from the queue, don't wait if its empty 
     while(my $xfoil_args = $queue->dequeue_nb) { 
      # Do the work 
      start_XFOIL_instance($xfoil_args); 
     } 

     # Yell when the thread is done 
     print "Queue empty\n"; 
    }); 
} 

# Wait for threads to finish 
$_->join for @threads; 

__DATA__ 
blah 
foo 
bar 
baz 
biff 
whatever 
up 
down 
left 
right 
+0

Tôi thấy nhận xét trước đó của tôi (hoặc câu trả lời trước của bạn) đã bị xóa, dù sao cảm ơn bạn đã cập nhật câu trả lời của mình. Tôi tò mò về, nếu bạn xác minh rằng các chủ đề có thể tận dụng lợi thế của nhiều lõi và bộ vi xử lý, nếu có, làm cách nào bạn xác minh nó? Cảm ơn =) – user454322

+0

@ user454322 Sau khi nhìn thấy bình luận của bạn, tôi đã viết một kịch bản nhỏ để thực hiện một vòng lặp vô hạn trong một chuỗi các chủ đề và sử dụng Activity Monitor trên OS X để thấy rằng tất cả bốn lõi đã được sử dụng.Bạn đang đúng về mô hình luồng là một thông dịch viên Perl mới cho mỗi chủ đề thực sự. Trước đây tôi đã nhận được nó trong đầu của tôi rằng nó đã được tất cả các mô phỏng trong một quá trình duy nhất. – Schwern

+0

Tôi đã đăng http://stackoverflow.com/questions/12536064/how-does-perls-threading-system-work, nếu bạn có cơ hội, hãy xem qua. – user454322

0

Bạn có xem gnu song song parallel hay không. Nó sẽ cho phép bạn chạy một số phiên bản cài đặt của chương trình của bạn với các đầu vào khác nhau và lấp đầy lõi CPU của bạn khi chúng bắt đầu có sẵn. Nó thường là một cách rất đơn giản để đạt được sự song song của các nhiệm vụ đơn giản.

0

này khá cũ nhưng nếu ai đó đang vẫn đang tìm kiếm câu trả lời thích hợp cho câu hỏi này, bạn có thể muốn xem xét Perl Many-Core-Engine (MCE)

Các vấn đề liên quan