2012-04-04 64 views
11

Chúng tôi có khoảng 500GB hình ảnh trong các thư mục khác nhau mà chúng tôi cần xử lý. Mỗi hình ảnh có kích thước khoảng 4MB và chúng tôi có một tập lệnh python để xử lý từng hình ảnh một lần (nó đọc siêu dữ liệu và lưu trữ nó trong một cơ sở dữ liệu). Mỗi thư mục có thể mất 1-4 giờ để xử lý tùy thuộc vào kích thước.Cách nhanh nhất để xử lý các tệp lớn trong Python

Hiện tại chúng tôi đang xử lý bộ xử lý lõi tứ 2,2 Ghz và RAM 16 GB trên hệ điều hành GNU/Linux. Kịch bản hiện tại chỉ sử dụng một bộ xử lý. Cách tốt nhất để tận dụng các lõi và RAM khác để xử lý hình ảnh nhanh hơn là gì? Sẽ bắt đầu nhiều quá trình Python để chạy kịch bản tận dụng lợi thế của các lõi khác?

Một tùy chọn khác là sử dụng một cái gì đó như Gearman hoặc Cây đậu để trang trại công việc cho các máy khác. Tôi đã xem xét thư viện đa xử lý nhưng không chắc chắn cách tôi có thể sử dụng nó.

+0

bản sao có thể có của [Cách sử dụng tất cả các lõi trong Windows 7?] (Http://stackoverflow.com/questions/3055696/how-to-use-all-the-cores-in-windows-7) –

+1

Nếu bạn đã có một tập lệnh làm việc mà bạn có thể trỏ vào bất kỳ tập tin/thư mục nào bạn muốn, hãy xem xét viết một kịch bản lệnh shell để xoay vòng bao nhiêu lần tùy ý bạn cần. –

+4

Tôi bắt đầu bằng cách nhìn vào vị trí cổ chai. Nếu bạn đang dành phần lớn thời gian của bạn thực hiện IO thì bạn sẽ không thể đi nhanh hơn nhiều. Ví dụ, nếu một quá trình duy nhất quản lý để tải dữ liệu từ đĩa ở một tốc độ nhất định, nó rất khó mà bạn sẽ có thể duy trì tốc độ đó khi nhiều quá trình nhai đĩa. –

Trả lời

6

Sẽ bắt đầu nhiều quy trình Python để chạy tập lệnh tận dụng lợi thế của các lõi khác?

Có, nó sẽ, nếu tác vụ được ràng buộc CPU. Đây có lẽ là lựa chọn dễ nhất. Tuy nhiên, không sinh ra một quá trình duy nhất cho mỗi tệp hoặc mỗi thư mục; xem xét sử dụng một công cụ như parallel(1) và để cho nó sinh ra một cái gì đó giống như hai quá trình trên mỗi lõi.

Một tùy chọn khác là sử dụng thứ gì đó như Gearman hoặc Cây đậu để nông nghiệp trong công việc cho các máy khác.

Điều đó có thể hiệu quả. Ngoài ra, có một cái nhìn tại Python binding for ZeroMQ, nó làm cho xử lý phân phối khá dễ dàng.

Tôi đã xem thư viện đa xử lý nhưng không chắc chắn cách tôi có thể sử dụng nó.

Xác định hàm, ví dụ process, đọc hình ảnh trong một thư mục, kết nối với cơ sở dữ liệu và lưu trữ siêu dữ liệu. Hãy để nó trả về một boolean cho thấy thành công hay thất bại. Hãy để directories là danh sách các thư mục cần xử lý. Sau đó,

import multiprocessing 
pool = multiprocessing.Pool(multiprocessing.cpu_count()) 
success = all(pool.imap_unordered(process, directories)) 

sẽ xử lý tất cả các thư mục song song. Bạn cũng có thể làm song song ở cấp độ tập tin nếu bạn muốn; mà chỉ cần một chút tinkering.

Lưu ý rằng điều này sẽ dừng lại ở lần thất bại đầu tiên; làm cho nó có khả năng chịu lỗi mất nhiều công sức hơn một chút.

4

Bắt đầu quy trình Python độc lập là lý tưởng. Sẽ không có sự tranh chấp khóa giữa các quá trình và hệ điều hành sẽ lên lịch cho chúng chạy đồng thời.

Bạn có thể muốn thử nghiệm để xem số lượng cá thể lý tưởng là gì - có thể nhiều hơn hoặc ít hơn số lượng lõi. Sẽ có tranh chấp cho đĩa và bộ nhớ cache, nhưng mặt khác, bạn có thể nhận được một tiến trình để chạy trong khi một tiến trình khác đang chờ I/O.

2

Xem answer đến số question này.

Nếu ứng dụng có thể xử lý phạm vi của dữ liệu đầu vào, sau đó bạn có thể khởi chạy 4 trường hợp của các ứng dụng với phạm vi khác nhau của dữ liệu đầu vào để xử lý và kết hợp các kết quả sau khi tất cả chúng đều thực hiện.

Mặc dù câu hỏi đó có vẻ là Windows cụ thể, nhưng nó áp dụng cho các chương trình luồng đơn trên tất cả hệ điều hành.

CẢNH BÁO: Ghi chú rằng quá trình này sẽ được I/O bị ràng buộc và quá nhiều truy cập đồng thời vào ổ cứng của bạn thực sự sẽ gây ra các quá trình như một nhóm để thực hiện chậm hơn xử lý tuần tự do cạnh tranh cho các I/O tài nguyên.

4

Bạn có thể sử dụng nhóm đa xử lý để tạo quy trình để tăng hiệu suất. Giả sử bạn có hàm handle_file để xử lý hình ảnh. Nếu bạn sử dụng lặp lại, nó chỉ có thể sử dụng tối đa 100% của một lõi của bạn. Để sử dụng nhiều lõi, xử lý đa hồ bơi tạo ra các quy trình con cho bạn và phân phối nhiệm vụ của bạn cho chúng. Dưới đây là ví dụ:

import os 
import multiprocessing 

def handle_file(path): 
    print 'Do something to handle file ...', path 

def run_multiprocess(): 
    tasks = [] 

    for filename in os.listdir('.'): 
     tasks.append(filename) 
     print 'Create task', filename 

    pool = multiprocessing.Pool(8) 
    result = all(list(pool.imap_unordered(handle_file, tasks))) 
    print 'Finished, result=', result 

def run_one_process(): 
    for filename in os.listdir('.'): 
     handle_file(filename) 

if __name__ == '__main__': 
    run_one_process 
    run_multiprocess() 

run_one_process là cách đơn lõi để xử lý dữ liệu, đơn giản nhưng chậm. Mặt khác, run_multiprocess tạo ra 8 quy trình công nhân và phân phối nhiệm vụ cho chúng. Nó sẽ nhanh hơn gấp 8 lần nếu bạn có 8 lõi. Tôi đề nghị bạn thiết lập số nhân viên để nhân đôi số lõi của bạn hoặc chính xác số lõi của bạn. Bạn có thể thử nó và xem cấu hình nào nhanh hơn.

Đối với máy tính phân tán nâng cao, bạn có thể sử dụng ZeroMQ làm larsmans được đề cập. Thật khó hiểu lúc đầu. Nhưng một khi bạn hiểu nó, bạn có thể thiết kế một hệ thống phân tán rất hiệu quả để xử lý dữ liệu của bạn. Trong trường hợp của bạn, tôi nghĩ rằng một REQ với nhiều REP sẽ là đủ tốt.

enter image description here

Hy vọng điều này sẽ hữu ích.

0

Nếu bạn đang đọc một số lượng lớn tệp và lưu siêu dữ liệu vào cơ sở dữ liệu, chương trình của bạn không cần nhiều lõi hơn.

Quá trình của bạn có khả năng là IO bị ràng buộc không bị ràng buộc CPU. Sử dụng xoắn với defereds thích hợp và callbacks có khả năng sẽ tốt hơn bất kỳ giải pháp mà tìm cách để tranh thủ 4 lõi.

0

Tôi nghĩ trong trường hợp này, bạn nên sử dụng Celery một cách hoàn hảo.

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