2012-01-23 24 views
5

Chúng tôi có một thư mục với 50 datafiles (chuỗi DNA thế hệ tiếp theo) cần được chuyển đổi bằng cách chạy tập lệnh python trên mỗi tệp. Kịch bản mất 5 giờ cho mỗi tập tin và nó là đơn luồng và phần lớn là CPU bị ràng buộc (lõi CPU chạy ở 99% với IO đĩa tối thiểu).Chạy 4 trường hợp đồng thời của một tập lệnh python trên một thư mục của các tệp dữ liệu

Vì tôi có một máy 4 lõi, tôi muốn chạy 4 phiên bản của tập lệnh này cùng một lúc để tăng tốc quá trình.

Tôi đoán tôi có thể chia dữ liệu thành 4 thư mục và chạy các script bash sau trên mỗi thư mục cùng một lúc:

files=`ls -1 *` 
for $file in $files; 
do 
    out = $file+=".out" 
    python fastq_groom.py $file $out 
done 

Nhưng có phải là một cách tốt hơn để chạy nó trên một thư mục . Chúng ta có thể sử dụng Bash/Python/Perl/Windows để làm điều này.
(Đáng buồn làm cho kịch bản đa luồng là xa hơn những gì chúng ta có thể làm)


Sử dụng @phs xargs giải pháp được cách dễ nhất để chúng ta giải quyết vấn đề. Tuy nhiên, chúng tôi yêu cầu nhà phát triển ban đầu triển khai câu trả lời @ Björn. Một lần nữa cảm ơn!

+2

Việc sử dụng của 'ls' trong backticks, và gán giá trị cho một biến để khởi động, là một antipattern thường xuyên. Nó sẽ phá vỡ trên tên tập tin với không gian, và nó sẽ phá vỡ nếu bạn có thư mục con. Thành ngữ chính xác là 'cho tệp trong *' - cũng lưu ý sự vắng mặt của một ký hiệu đô la khi đặt tên một biến; bạn sử dụng ký hiệu đô la khi nội suy một biến. Xem thêm http://partmaps.org/era/unix/award.html#ls – tripleee

+0

@triplee Cảm ơn bạn đã tip –

Trả lời

1

Hãy xem xargs. Đó là tùy chọn -P cung cấp một mức độ cấu hình song song. Cụ thể, một cái gì đó như thế này nên làm việc cho bạn:

ls files* | awk '{print $1,$1".out"}' | xargs -P 4 -n 2 python fastq_groom.py 
+1

điều này sẽ vi phạm với các tệp có khoảng trắng trong tên của họ và có thể là các phần tử khác như dòng mới và tương tự – SiegeX

7

Bạn có thể sử dụng mô hình multiprocessing. Tôi cho rằng bạn có một danh sách các tập tin để xử lý và một chức năng để gọi cho mỗi tập tin. Sau đó, bạn có thể chỉ cần sử dụng nhóm công nhân như sau:

from multiprocessing import Pool, cpu_count 

pool = Pool(processes=cpu_count) 
pool.map(process_function, file_list, chunksize=1) 

Nếu số process_function không trả lại giá trị, bạn có thể đơn giản bỏ qua giá trị trả về.

1

này cung cấp cho một shot:

#!/bin/bash 

files=(*) 
for((i=0;i<${#files[@]};i+=4)); do 
    { 
    python fastq_groom.py "${files[$i]}" "${files[$i]}".out & 
    python fastq_groom.py "${files[$i+1]}" "${files[$i+1]}".out & 
    python fastq_groom.py "${files[$i+2]}" "${files[$i+2]}".out & 
    python fastq_groom.py "${files[$i+3]}" "${files[$i+3]}".out & 
    } 
done 

Các puts sau tất cả các file vào một mảng có tên files. Nó sau đó thực hiện và nền bốn quá trình python trên bốn tập tin đầu tiên. Ngay sau khi tất cả bốn của các quy trình đó hoàn tất, nó sẽ thực hiện bốn bước tiếp theo. Nó không phải là hiệu quả như luôn luôn giữ một hàng đợi của 4 đi nhưng nếu tất cả các quá trình mất khoảng cùng một khoảng thời gian, nó phải được khá gần đó.

Ngoài ra, vui lòng không sử dụng đầu ra của ls như thế. Chỉ cần sử dụng globbing tiêu chuẩn như trong for files in *.txt; do ...; done

0

Nếu bạn đã GNU Song song bạn có thể làm:

parallel python fastq_groom.py {} {}.out ::: files* 

Nó sẽ làm The Right Thing do đẻ trứng một công việc cho mỗi lõi, ngay cả khi tên của tập tin của bạn có nhiều không gian, Nó cũng đảm bảo đầu ra từ các công việc khác nhau không được trộn lẫn với nhau, vì vậy nếu bạn sử dụng đầu ra, bạn được đảm bảo rằng bạn sẽ không nhận được nửa dòng từ hai công việc khác nhau.

GNU Song song là một bộ song song chung và giúp dễ dàng thực hiện các công việc song song trên cùng một máy hoặc trên nhiều máy mà bạn có quyền truy cập ssh.

Nếu bạn có 32 công việc khác nhau mà bạn muốn chạy trên 4 CPU, một cách thẳng về phía trước để parallelize là chạy 8 việc làm trên mỗi CPU:

Simple scheduling

GNU Parallel thay spawns một quá trình mới khi một kết thúc - giữ CPU hoạt động và do đó tiết kiệm thời gian:

GNU Parallel scheduling

Lắp đặt

Nếu GNU Parallel không được đóng gói cho bản phân phối của bạn, bạn có thể thực hiện cài đặt cá nhân, không yêu cầu quyền truy cập gốc. Nó có thể được thực hiện trong 10 giây bằng cách làm này:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

Đối với tùy chọn cài đặt khác nhìn thấy http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Tìm hiểu thêm

Xem thêm ví dụ: http://www.gnu.org/software/parallel/man.html

Xem video giới thiệu: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Đi qua t anh hướng dẫn: http://www.gnu.org/software/parallel/parallel_tutorial.html

Đăng ký cho danh sách email để nhận được hỗ trợ: https://lists.gnu.org/mailman/listinfo/parallel

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