Tôi có một tập lệnh python mà tôi đã viết bằng cách sử dụng mô-đun đa xử lý, để thực thi nhanh hơn. Việc tính toán là một cách lúng túng song song, do đó hiệu quả sẽ tăng lên với số lượng bộ vi xử lý. Bây giờ, tôi muốn sử dụng điều này trong một chương trình MPI, quản lý một phép tính MCMC trên nhiều máy tính. Mã này có một cuộc gọi đến hệ thống() mà gọi kịch bản python. Tuy nhiên, tôi thấy rằng khi nó được gọi là cách này, hiệu quả đạt được từ việc sử dụng đa xử lý python biến mất.Đa xử lý Python trong mpi
Làm cách nào để lấy tập lệnh python để giữ lại tốc độ tăng từ quá trình xử lý đa khi được gọi từ MPI?
Dưới đây là một ví dụ đơn giản, tương tự với các mã phức tạp hơn nhiều mà tôi muốn sử dụng nhưng hiển thị cùng một hành vi chung. Tôi viết một kịch bản python thực thi được gọi là junk.py.
#!/usr/bin/python
import multiprocessing
import numpy as np
nproc = 3
nlen = 100000
def f(x):
print x
v = np.arange(nlen)
result = 0.
for i, y in enumerate(v):
result += (x+v[i:]).sum()
return result
def foo():
pool = multiprocessing.Pool(processes=nproc)
xlist = range(2,2+nproc)
print xlist
result = pool.map(f, xlist)
print result
if __name__ == '__main__':
foo()
Khi tôi tự chạy từ vỏ, sử dụng "trên cùng", tôi có thể thấy ba quy trình python mỗi 100% CPU trên máy 16 lõi của tôi.
node094:mpi[ 206 ] /usr/bin/time junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
62.68user 0.04system 0:21.11elapsed 297%CPU (0avgtext+0avgdata 16516maxresident)k
0inputs+0outputs (0major+11092minor)pagefaults 0swaps
Tuy nhiên, nếu tôi gọi điều này bằng mpirun, mỗi quá trình python chiếm 33% CPU và tổng thể mất khoảng ba lần để chạy. Gọi với -np 2 hoặc nhiều kết quả trong nhiều quy trình hơn, nhưng không tăng tốc độ tính toán bất kỳ.
node094:mpi[ 208 ] /usr/bin/time mpirun -np 1 junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
61.63user 0.07system 1:01.91elapsed 99%CPU (0avgtext+0avgdata 16520maxresident)k
0inputs+8outputs (0major+13715minor)pagefaults 0swaps
(Ghi chú thêm: Đây là mpirun 1.8.1, python 2.7.3 trên phiên bản Linux Debian khò khè hệ thống tôi đã nghe nói() không phải luôn luôn cho phép trong phạm vi chương trình MPI, nhưng nó đã làm việc cho tôi cho. Ví dụ, tôi đã gọi một mã song song dựa trên pthread từ system() trong một chương trình MPI, và nó được sử dụng 100% cpu cho mỗi luồng, như mong muốn. Ngoài ra, trong trường hợp bạn định đề xuất chạy kịch bản python trong serial và chỉ gọi nó trên nhiều nút hơn ... tính toán MCMC liên quan đến một số chuỗi cố định cần di chuyển theo cách được đồng bộ hóa, do đó tính toán không may không thể được tổ chức lại theo cách đó.)
để câu trả lời là tắt tính năng đa xử lý trong tập lệnh? – Cmag
Xin lỗi, câu trả lời cho phần nào? Việc khởi chạy với --bind-to none sẽ tránh được sự cố CPU.Đối với vấn đề với fork, mpirun/mpiexec của OpenMPI sẽ cho bạn biết nếu bạn đang chạy trong các tình huống mà fork-ing không an toàn, và bạn có thể giải quyết vấn đề đó khi/nếu nó phát sinh. –
Tôi đã xác nhận giải pháp này hoạt động, cả với ví dụ đơn giản và mã thực của tôi. Cảm ơn rất nhiều! Tôi đoán hành vi này của mpirun thay đổi cùng với các tùy chọn liên kết trong phiên bản 1.7 của openmpi, nếu không thì tôi không thể thấy tại sao một số mã tôi đã chạy trước đó sẽ hoạt động. –