Tôi có một danh sách các từ điển và tôi sử dụng từng từ điển để thực hiện một số thao tác trên biểu đồ. Quá trình xử lý này được thực hiện trong một hàm không trả về gì.
Không có thao tác I/O và không có kết nối mạng, về cơ bản nó chỉ là tính toán; mỗi từ điển biểu thị một đường dẫn trong biểu đồ và tôi cần cập nhật trọng số cạnh của đường dẫn đó. Hiện tại tôi không quan tâm đến tính nhất quán của dữ liệu được lưu trữ trên biểu đồ, tôi chỉ muốn cải thiện thời gian xử lý.
tôi đầu tiênnối tiếp, xử lý từng mục trong vòng lặp for:
def processDict(dic, đồ thị):
# Sửa đổi biểu đồ theo dữ liệu được lưu trong từ điển
# Không trả về gì
cập nhật defPheromone(listOfDicts):
# Có thể truy cập đồ thị trong phạm vi của hàm này
cho dic trong listOfDicts:
processDict(dic, đồ thị)
Sau đó tôi quyết định thử song song hóa nó vì danh sách từ điển có thể chứa tới hàng chục nghìn từ điển và tôi có thể truy cập chúng trên máy tính có nhiều CPU. Nỗ lực đầu tiên của tôi là sử dụng luồng module, nhưng kết quả còn tệ hơn nhiều so với phiên bản nối tiếp. Đọc một số câu hỏi ở đây trên SO và trên web, tôi đã tìm thấy một số đề xuất để sử dụng lớp multiprocessing.Pool thay vì các luồng do GIL. Kết quả tốt hơn so với việc chỉ sử dụng các luồng, nhưng phiên bản nối tiếp vẫn hoạt động tốt hơn (mất khoảng một nửa thời gian trên PC lõi tứ!). Đây là những gì tôi đã thử cho phiên bản song song này:
từ nhập đa xử lý Pool, cpu_count
từ functools nhập một phần
cập nhật defPheromone(listOfDicts):
# Có thể truy cập đồ thị trong phạm vi của hàm này
hồ bơi = Bể bơi()
một phần_Func = một phần (processDict, đồ thị = đồ thị)
pool.map_async(partial_Func, listOfDicts, len(listOfDicts)/cpu_count())
pool.close()
Tôi cảm thấy như mình đang gặp vấn đề với cách tiếp cận này. Hiệu suất kém có liên quan đến chức năng được truyền tới bản đồ không?"khoảng trống" Chức năng liên quan? Có thư viện hoặc lớp nào khác mà tôi nên sử dụng không?
EDIT: Tôi đang chạy cái này trên Linux.
Tôi cảm thấy mình đang hiểu sai điều gì đó trong cách tiếp cận này.
Nguyên nhân có thể là do có quá nhiều dữ liệu được truyền vào.
Các quy trình không chia sẻ bộ nhớ, do đó, mọi dữ liệu bạn truyền vào đều phải được tuần tự hóa ở một bên, được truyền qua một kênh (như ổ cắm thô) và được giải tuần tự hóa ở phía bên kia. Nếu tiêu tốn nhiều thời gian hơn thời gian tiết kiệm được bằng cách xử lý song song thì kết quả là tổn thất ròng.
Một kỹ thuật để xử lý vấn đề này là biến biểu đồ trong bộ nhớ thành biến toàn cục trước khi tạo nhóm(Điều này cho phép chia sẻ dữ liệu thông qua tính năng sao chép khi ghi). Sau đó, chỉ cần chuyển chỉ mục (số đơn) cho quy trình và để nó hoạt động trên phần riêng của biểu đồ.
Tôi là một lập trình viên xuất sắc, rất giỏi!