2012-04-04 30 views
43

Tôi gặp khó khăn khi hiểu khái niệm chặn giao tiếp liên lạc và không chặn trong MPI. Đâu là sự khác biệt giữa cả hai? Ưu điểm và nhược điểm là gì?mpi: chặn và không chặn

Cảm ơn!

Trả lời

58

Giao tiếp chặn được thực hiện bằng cách sử dụng MPI_Send()MPI_Recv(). Các chức năng này không trả lại (tức là chúng sẽ bị chặn) cho đến khi kết thúc giao tiếp. Đơn giản hóa một chút, điều này có nghĩa là bộ đệm được chuyển đến MPI_Send() có thể được sử dụng lại, hoặc vì MPI đã lưu nó ở đâu đó, hoặc bởi vì nó đã được nhận bởi đích. Tương tự, MPI_Recv() trả về khi bộ đệm nhận đã được lấp đầy với dữ liệu hợp lệ.

Ngược lại, giao tiếp không chặn được thực hiện bằng cách sử dụng MPI_Isend()MPI_Irecv(). Các hàm này trả về ngay lập tức (tức là chúng không bị chặn) ngay cả khi giao tiếp chưa kết thúc. Bạn phải gọi MPI_Wait() hoặc MPI_Test() để xem liệu liên lạc đã kết thúc chưa.

Giao tiếp chặn được sử dụng khi đủ, vì nó dễ sử dụng hơn. Giao tiếp không chặn được sử dụng khi cần thiết, ví dụ: bạn có thể gọi MPI_Isend(), thực hiện một số tính toán, sau đó thực hiện MPI_Wait(). Điều này cho phép tính toán và giao tiếp để chồng lên nhau, thường dẫn đến hiệu suất được cải thiện.

Lưu ý rằng giao tiếp tập thể (ví dụ: tất cả giảm) chỉ có sẵn trong phiên bản chặn của nó lên đến MPIv2. IIRC, MPIv3 giới thiệu giao tiếp tập thể không chặn.

Tổng quan nhanh về chế độ gửi của MPI có thể được xem here.

+1

sao cho MPI_Send() giống với MPI_Isend() + MPI_Wait()? – lamba

+0

Có, ngoại trừ trên không, bạn có thể nghĩ MPI_Send() là một MPI_Isend() theo sau là một MPI_Wait(). – user1202136

+11

@ user1202136: Bạn có thể muốn đề cập rằng 'MPI_Send' hoàn thành khi bạn có thể sử dụng lại bộ đệm, độc lập với việc người nhận đã nhận được dữ liệu (hay thậm chí dữ liệu đã được gửi chưa). –

8

Trong việc sử dụng thông tin liên lạc chặn bạn phải chăm sóc về gửi và nhận các cuộc gọi ví dụ nhìn vào mã này

if(rank==0) 
{ 
    MPI_Send(x to process 1) 
    MPI_Recv(y from process 1) 
} 
if(rank==1) 
{ 
    MPI_Send(y to process 0); 
    MPI_Recv(x from process 0); 
} 

gì sẽ xảy ra trong trường hợp này?

  1. Quy trình 0 gửi x để xử lý 1 và chặn cho đến khi quá trình 1 nhận x.
  2. Quy trình 1 gửi y xử lý 0 và chặn cho đến khi quá trình 0 nhận được y, nhưng
  3. quy trình 0 bị chặn như vậy quy trình 1 khối cho vô cùng cho đến khi hai quá trình bị giết.
+4

Tôi đã từng nghĩ như vậy. Nhưng khi tôi sử dụng MPI_Send trên máy tính của mình, tôi thấy vấn đề bên trong có thể phức tạp hơn. Đoạn mã trên hoạt động vì nó có thể di chuyển thư đến bộ đệm. Chỉ 'MPI_Ssend' là đúng * chặn *, vì nó trả về cho đến khi đích nhận được tin nhắn. Các liên kết sau giải thích rằng các nhà cung cấp khác nhau chọn triển khai khác nhau. http://www.mcs.anl.gov/research/projects/mpi/sendmode.html –

3

Thật dễ dàng.

Không chặn nghĩa là tính toán và truyền dữ liệu có thể xảy ra cùng một lúc cho một quy trình.

Khi Chặn có nghĩa là, bạn thân, bạn phải đảm bảo rằng bạn đã hoàn tất chuyển dữ liệu rồi quay trở lại để hoàn thành lệnh tiếp theo, có nghĩa là nếu có chuyển đổi theo sau tính toán, tính toán phải sau thành công chuyển giao.

+0

cảm ơn tuyệt vời của nó @Pab Peter –

3

Bài đăng này, mặc dù có một chút cũ, nhưng tôi tranh luận câu trả lời được chấp nhận. tuyên bố "Những chức năng này không trở lại cho đến khi giao tiếp kết thúc" là một chút sai lầm vì việc chặn liên lạc không đảm bảo bất kỳ cái bắt tay nào b/w hoạt động gửi và nhận.

Đầu tiên cần phải biết, gửi có bốn chế độ giao tiếp: Standard, đệm, đồng bộReady và mỗi người trong số chúng có thể được chặnnon-blocking

Không giống như gửi, chỉ nhận được một chế độ và có thể là chặn hoặc không chặn.

BẬT THÔNG TIN: Chặn không có nghĩa là thư được gửi đến người nhận/đích. Nó chỉ đơn giản có nghĩa là bộ đệm (gửi hoặc nhận) có sẵn để tái sử dụng. Để tái sử dụng bộ đệm, nó đủ để sao chép thông tin vào vùng bộ nhớ khác, tức là thư viện có thể sao chép dữ liệu đệm để sở hữu vị trí bộ nhớ trong thư viện và sau đó, ví dụ: MPI_Send có thể trả về.

Tiêu chuẩn MPI làm cho nó rất rõ ràng để tách thông báo đệm khỏi các hoạt động gửi và nhận. Việc gửi chặn có thể hoàn tất ngay sau khi thư được lưu vào bộ đệm, mặc dù không có nhận được kết quả nào được đăng. Nhưng trong một số trường hợp, việc gửi thư có thể tốn kém và do đó việc sao chép trực tiếp từ bộ đệm gửi để nhận bộ đệm có thể hiệu quả. Do đó MPI Standard cung cấp bốn chế độ gửi khác nhau để cung cấp cho người dùng một số quyền tự do trong việc chọn chế độ gửi thích hợp cho ứng dụng của mình. Cho phép hãy nhìn vào những gì xảy ra trong mỗi phương thức giao tiếp:

1. Tiêu chuẩn Chế độ

Trong tiêu chuẩn chế độ, nó tùy thuộc vào thư viện MPI, có hoặc không để đệm thông điệp gửi đi . Trong trường hợp thư viện quyết định đệm thư gửi đi, gửi có thể hoàn thành ngay cả trước khi nhận được kết hợp đã được gọi. Trong trường hợp thư viện quyết định không đệm (vì lý do hiệu suất, hoặc do không có vùng bộ đệm), việc gửi sẽ không trả lại cho đến khi nhận được kết nối và dữ liệu trong bộ đệm gửi đã được chuyển đến bộ đệm nhận.

Do đó MPI_Send ở chế độ chuẩn là không phải địa phương theo nghĩa là gửi ở chế độ tiêu chuẩn có thể được bắt đầu có nhận được kết nối hay không. thực tế nó được thực hiện phụ thuộc nếu tin nhắn sẽ được đệm hay không).

Cú pháp để gửi các ý kiến ​​dưới đây:

int MPI_Send(const void *buf, int count, MPI_Datatype datatype, 
      int dest, int tag, MPI_Comm comm) 

2. Buffered Chế độ

Giống như ở chế độ tiêu chuẩn, gửi trong chế độ đệm có thể được bắt đầu không phụ thuộc vào thực tế là một khớp nhận được đăng và gửi có thể hoàn tất trước khi nhận được kết quả đã được đăng. Tuy nhiên sự khác biệt chính phát sinh từ thực tế là nếu gửi được nhìn chằm chằm và không nhận được kết nối được gửi các tin nhắn gửi đi phải được đệm. Lưu ý nếu nhận được kết nối được gửi, gửi đệm có thể vui vẻ hẹn với bộ xử lý bắt đầu nhận, nhưng trong trường hợp không nhận được, gửi ở chế độ đệm phải đệm thư gửi đi để cho phép gửi hoàn tất.Nói chung, gửi thư được gửi là địa phương. Việc cấp phát bộ đệm trong trường hợp này là do người dùng xác định và trong trường hợp không đủ vùng đệm, một lỗi xảy ra.

Cú pháp để gửi đệm:

int MPI_Bsend(const void *buf, int count, MPI_Datatype datatype, 
      int dest, int tag, MPI_Comm comm) 

3. Synchronous Chế độ

Trong chế độ gửi đồng bộ, gửi có thể được bắt đầu hay không phù hợp với nhận được đã được đăng. Tuy nhiên việc gửi sẽ hoàn tất thành công chỉ khi một nhận phù hợp đã được đăng và người nhận đã bắt đầu nhận được tin nhắn được gửi bằng cách gửi đồng bộ. Việc hoàn thành việc gửi đồng bộ không chỉ cho thấy rằng bộ đệm trong quá trình gửi có thể được tái sử dụng, mà còn thực tế là quá trình nhận đã bắt đầu nhận dữ liệu. Nếu cả hai gửi và nhận đang chặn thì giao tiếp không hoàn thành ở hai đầu trước khi bộ xử lý giao tiếp gặp nhau.

Cú pháp để gửi đồng bộ:

int MPI_Ssend(const void *buf, int count, MPI_Datatype datatype, int dest, 
       int tag, MPI_Comm comm) 

4. Ready Chế độ

Khác với ba chế độ trước đó, một gửi trong chế độ sẵn sàng có thể chỉ bắt đầu nếu phù hợp nhận được đã được đăng. Việc hoàn thành việc gửi không chỉ ra bất cứ điều gì về việc nhận phù hợp và chỉ nói rằng bộ đệm gửi có thể được sử dụng lại. Một gửi sử dụng chế độ sẵn sàng có cùng ngữ nghĩa như chế độ tiêu chuẩn hoặc chế độ đồng bộ với thông tin bổ sung về nhận phù hợp. Một chương trình chính xác với một phương thức giao tiếp sẵn sàng có thể được thay thế bằng gửi đồng bộ hoặc gửi tiêu chuẩn mà không ảnh hưởng đến kết quả ngoài hiệu suất khác biệt.

Cú pháp để gửi ready:

int MPI_Rsend(const void *buf, int count, MPI_Datatype datatype, int dest, 
       int tag, MPI_Comm comm) 

May mắn thay MPI đã quyết định giữ cho mọi thứ easer cho người sử dụng về mặt nhận và chỉ có một nhận trong Chặn liên lạc: MPI_Recv, và có thể được sử dụng với bất kỳ của bốn chế độ gửi được mô tả ở trên. Đối với MPI_Recv, chặn nghĩa là chỉ nhận trả về sau khi nó chứa dữ liệu trong bộ đệm của nó. Điều này ngụ ý rằng việc nhận có thể hoàn thành chỉ sau khi một lần gửi phù hợp đã bắt đầu nhưng không ngụ ý liệu nó có thể hoàn thành trước khi quá trình gửi phù hợp hoàn thành hay không.

Điều gì xảy ra trong các cuộc gọi chặn này là các tính toán được tạm dừng cho đến khi bộ đệm bị chặn được giải phóng. Điều này thường dẫn đến lãng phí tài nguyên tính toán như Gửi/Recv thường sao chép dữ liệu từ một vị trí bộ nhớ đến một vị trí bộ nhớ khác, trong khi thanh ghi trong cpu vẫn không hoạt động.

KHÔNG BẬT THÔNG TIN: Đối với giao tiếp không chặn, ứng dụng tạo yêu cầu liên lạc để gửi và/hoặc nhận lại và xử lý rồi chấm dứt. Đó là tất cả những gì cần thiết để đảm bảo rằng quá trình được thực hiện. I. Thư viện MPI được thông báo rằng thao tác phải được thực thi.

Đối với phía người gửi, điều này cho phép tính toán chồng chéo với giao tiếp.

Đối với phía người nhận, điều này cho phép chồng chéo một phần chi phí truyền thông, tức là sao chép thông báo trực tiếp vào không gian địa chỉ của bên nhận trong ứng dụng.