Truyền thông đồng bộ

Một phần của tài liệu Kỹ Thuật Đường Ống Và Cân Bằng Tải Trong Lập Trình Song Song MPI (Trang 41 - 49)

Truyền thông điệp đồng bộ: Trong mô hình này, tiến trình gửi bị chặn lại cho đến khi tiến trình nhận sẵn sàng nhận. Ở đây, sự truyền thông và đồng bộ hoá luôn gắn chặt với nhau.

Hệ thống truyền thông điệp đồng bộ hoàn toàn giống như hệ điện thoại, kênh truyền bị chặn lại trong quá trình đàm thoại. Hệ truyền dị bộ lại giống nhiều hơn với hệ thống bưu chính, người nhận phải chờ cho đến khi có thư được gửi đến.

Chúng ta hãy phân tích thêm để hiểu rõ sự phát triển của hai mô hình trên. Một mặt, cơ chế truyền thông điệp đồng bộ làm cho nhiều vấn đề trong đồng bộ hoá và việc cấp phát bộ nhớ động trở lên đơn giản hơn. Mặt khác, việc gắn chặt các tiến trình với thời gian phân phát thông điệp cũng được xem như là điều kiện ràng buộc bổ sung đòi hỏi trong thiết kế và thực thi chương trình. Việc bắt tiến trình gửi phải chờ dẫn đến việc làm giảm tính đồng thời của hệ thống. Ngoài ra, để cài đặt hiệu quả các hệ thống truyền tin đồng bộ, đòi hỏi phải có những phần cứng đặc biệt để đảm bảo rằng sự truyền tin cực nhanh và sự trao đổi dữ liệu không ảnh hưởng tới sự tính toán. Mà các mạng truyền thông nhanh có nhiều nút trao đổi với nhau là rất đắt tiền. Vì những lý do trên, nên hệ truyền thông điệp dị bộ làm việc trên LAN sẽ ngày một phổ cập hơn.

Các chương trình truyền thông điệp hiển thị nhiều mẫu giao diện khác nhau. Sau đây là một số mẫu chung nhất:

 Dòng dữ liệu một chiều từ các bộ lọc trên mạng

 Các yêu cầu và trả lời qua lại giữa khách (Client) và chủ (Server)

 Gửi các dấu hiệu (token) theo các cạnh của đồ thị, v.v.

2.1.4 Truyền thông dị bộ

Truyền thông điệp dị bộ: Trong mô hình này, một kênh truyền được giả thiết là có khả năng tiếp nhận không bị giới hạn. Khả năng không giới hạn được cài đặt trong thực tế bằng cách sử dụng bộ đệm (buffer) để tiếp nhận các thông điệp gửi đến cho mỗi tiến trình. Do vậy, tiến trình gửi sẽ không phải chờ để tiến trình nhận sẵn sàng nhận mà cứ gửi khi có yêu cầu. Như vậy, hai tiến trình gửi và nhận có thể hoạt động gần như độc lập với nhau và thông điệp có thể nhận được sau một khoảng thời gian nào đó (lâu bất kỳ) kể từ khi nó được gửi đi. Tuy nhiên, tiến trình nhận thì phải chờ cho đến khi có được thông điệp của một tiến trình khác gửi cho nó. Từ đó dẫn đến một số điều kiện:

oKhi tiến trình A gửi đi một thông điệp cho tiến trình B thì sau đó nó cần phải được biết xem B có nhận được hay không, nghĩa là A phải chờ để nhận được câu trả lời khẳng định của B.

oViệc phân phát thông điệp cũng không thể đảm bảo rằng không bị thất bại. Nếu A gửi đi một thông điệp cho B và không nhận được câu trả lời thì nó cũng không có cách nào biết được là thông điệp đó đã được gửi đến đích chưa hoặc tiến trình B bị huỷ bỏ trong quá trình xử lý hoặc ngay cả khi câu trả lời của B không đến được A.

oTất cả các thông điệp đều phải đưa vào bộ đệm (hàng đợi), nhưng trong thực tế không gian hàng đợi là hữu hạn. Khi có quá nhiều thông điệp được gửi đi thì hoặc chương trình sẽ không thực hiện được hoặc phương thức gửi bị chặn lại. Điều này vi phạm ngữ nghĩa của mô hình truyền thông điệp dị bộ.

2.1.5 Mô hình lập trình 2.1.5.1 Phát sinh tiến trình

Một chức năng quan trọng trong lập trình song song là tạo lập ra nhiều tiến trình để thực hiện những công việc con của một chương trình song song. Nói chung, một chương trình bắt đầu thực hiện như một tiến trình và sau đó phát sinh ra

nhiều tiến trình con để khai thác khả năng song song của bài toán. Có hai cách tạo lập tiến trình: tạo lập tĩnh và tạo lập động.

 Tạo lập tiến trình tĩnh: tất cả các tiến trình được xác định trước khi thực hiện và hệ thống có một số tiến trình xác định trước. Trong hệ thống loại này thường có một tiến trình điều khiển còn được gọi là tiến trình “chủ” (master), những tiến trình khác được gọi là tiến trình tớ (slave). Đây là mô hình SPMD (simple-program, multipe-data). Sau khi chương trình nguồn được viết với các lệnh phân chia công việc cho từng tiến trình, nó sẽ được dịch sang mã thực thi được cho những tiến trình đó. Quá trình này được mô tả như hình 2.1

Hình 2.1 Dịch đơn chương trình, đa thao tác dữ liệu

Tạo lập tiến trình động: các tiến trình được tạo lập sau đó chúng có thể thực hiện trong các tiến trình khác. Các tiến trình có thể được tạo lập mới hoặc bị huỷ bỏ có điều kiện và một số tiến trình có thể thay đổi trong quá trình thực hiện. Mô hình cho phép thực hiện tạo lập động là MPMD (Muliple-program muliple-data), trong đó những chương trình khác nhau có thể thực hiện trên những bộ xử lý khác nhau. Tất cả các hệ thư viện truyền thông điệp đều có hàm phát sinh các tiến trình con với cấu trúc tổng quát như sau:

spawn(prog: string, host: int, count: int, id[]:int)

 prog: tên chương trình được nạp xuống như là chương trình con. Kết quả khi thực hiện thành công sẽ trả lại mảng id là địa chỉ của các tiến trình

được tạo ra để truyền thông điệp. Mảng id có chỉ số từ 1, tiến trình đầu tiên của chương trình song song có chỉ số là 0.

 host: tên của tiến trình mà ở đó các tiến trình con được tạo ra.

 count: số các đại diện của chương trình được tạo ra.

2.1.5.2 Hàm send và receive

Việc gửi một thông điệp được thực hiện bằng cách xác định địa chỉ của một hay tất cả các tiến trình nhận theo một kênh truyền. Lựa chọn thông điệp để nhận có thể dựa vào tiến trình gửi, kênh truyền, hay thẻ bài (tag) của thông điệp, v.v.

Lời gọi send() là không bị chặn, không phải chờ câu trả lời của nơi nhận. Nhưng lời gọi receive() sẽ bị chặn lại, chỉ có tiếp tục khi có một thông điệp tương ứng đã được gửi đi.

1. Gửi thông điệp cho một tiến trình id: send(id: int, message: message_type);

send(id: int, tag: int, message: message_type);

2. Gửi thông điệp tới một kênh: một thông điệp có thể gửi cho tất cả các tiến trình trên cùng một kênh mych.

send(mych: channel, message: message_type); (adsbygoogle = window.adsbygoogle || []).push({});

3. Nhận thông điệp từ một kênh: để nhận một thông điệp đang chờ đợi từ một kênh thì có thể sử dụng lời gọi hàm sau:

receive(mych: channel, message: message_type);

Nếu thông điệp được ghi thẻ thì tiến trình nhận có thể phân loại thông điệp trong hộp nhận và chọn thông điệp theo thẻ xác định.

receive(id: int, tag: int, msg: message_type); Ví dụ: trong C chúng ta có thể gọi

send(&x, destination_id); trong tiến trình nguồn và gọi

receive(&y, source_id);

Ở tiến trình đích để gửi giá trị dữ liệu x từ tiến trình nguồn (source-id) sang biến y cho tiến trình đích. Tất nhiên là x, y phải có cùng kiểu (kiểu tương thích với nhau) và cùng kích cỡ.

Hình 2.2 Sự trao đổi thông điệp giữa hai tiến trình

Như ở trên đã phân tích, việc gửi và nhận thông điệp có thể thực hiện một cách đồng bộ hoặc dị bộ. Trong trao đổi thông điệp đồng bộ, tiến trình gửi trước tiên phải gửi đi yêu cầu gửi và nó phải chờ đến khi nhận được câu trả lời sẵn sàng nhận của tiến trình đích thì mới tiến hành gửi. Ngược lại, khi có một tiến trình muốn nhận một thông điệp thì nó phải chờ để có một tiến trình khác gửi cho nó thì sau đó mới tiếp tục công việc. Trong mô hình dị bộ thì các thông điệp được gửi đi và được đưa vào bộ đệm để sau đó gửi dần tới cho các tiến trình đích. Để linh hoạt cho việc trao đổi, người ta thường gán cho mỗi thông điệp một thẻ bài (tag) và nó được sử dụng để phân biệt các thông điệp trao quá trình trao đổi. Ví dụ: để gửi thông điệp x từ tiến trình số 1 tới tiến trình số 2 và gán cho y, ta viết:

send(&x, 2, 5);

ở tiến trình số 1 và ở tiến trình số 2 gọi receive(&y, 1, 5);

2.1.5.3 Truyền thông nhóm

Nhiều chương trình phân tán cần phát tán và nhận dữ liệu từ nhiều tiến trình phân tán, nghĩa là cần trao đổi với từng nhóm trong chương trình song song. Để thực hiện truyền thông theo nhóm, chúng ta có thể sử dụng:

1. Broacast(): phát tán cùng một thông điệp cho tất cả các tiến trình trên kênh mych.

Broadcast(mych:channel,tag:int, msg:message_type);

Hoạt động của lệnh Broadcast() được mô tả như hình 2.3. Các tiến trình tham gia trao đổi trong phát tán dữ liệu phải được xác định. Trong hình 2.3, tiến trình số 0

được xem như tiến trình gốc chứa dữ liệu ở mảng buf để phát tán cho những tiến trình khác. Theo qui ước của mô hình SPMD, mọi tiến trình đều thực hiện cùng một chương trình nên trong hình 2.3 tất cả các tiến trình đều gọi hàm Broadcast(). Hành động phát tán dữ liệu sẽ không thực hiện được cho đến khi tất cả các tiến trình đều thực hiện lời gọi Broadcast().

Hình 2.3 Hoạt động phát tán dữ liệu

2. Reduce(): thực hiện phép toán số học/logic trong nhóm các tiến trình và gửi kết quả tới tiến trình gốc.

3. Reduce(mych:channel,op:op_type, res:Result_type,root: int,tag:int, msg:message_type);

Trong đó,

Op_type = {MAX, MIN, SUM, PROD, LAND, LOR, BAND, BOR, LXOR, BXOR}} Ví dụ: hình 2.4 mô tả hàm Reduce() tập hợp các giá trị từ n tiến trình và thực hiện phép cộng (SUM) ở tiến trình gốc.

Hình 2.4 Hoạt động của hàm Reduce()

4. Scatter(): phân tán công việc cho các tiến trình. Dữ liệu ở mảng buff được chia nhỏ thành n đoạn và phân tán cho n tiến trình trên kênh mych.

Hàm này được sử dụng để gửi phần tử thứ i của một mảng dữ liệu tới cho tiến trình thứ i. Hình 2.5 mô tả hoạt động của Scatter(). Tương tự trường hợp của Broadcast(), ở đây nhóm các tiến trình kể cả tiến trình gốc phải được xác định.

Hình 2.5 Hoạt động của hàm Scatter() (adsbygoogle = window.adsbygoogle || []).push({});

5. Gather(): ngược lại so với hàm Scatter(), dữ liệu được gửi đi theo hàm Scatter() được xử lý bởi những tiến trình nhận được và sau đó được tập hợp lại cho một tiến trình.

Gather(mych:channel,Buff[N]:DataType,root:int,sendbuff[N]:DataType); Ngược lại hàm Scatter(), dữ liệu từ tiến trình thứ i được nhận về ở tiến trình gốc và được đưa vào phần tử thứ i của mảng buf, được mô tả như hình 2.5.

Hình 2.6 Hoạt động của hàm Gather()

6. Barrier(): thực hiện việc đồng bộ hoá những tiến trình cùng gia nhập một kênh truyền. Mỗi tiến trình phải chờ cho đến khi tất cả các tiến trình khác trên kênh đạt đến điểm đồng bộ hoá bằng lời gọi Barrier() trong chương trình.

2.2 MPI

Để khuyến khích việc sử dụng và mở rộng hệ thống truyền thông điệp, một nhóm các đối tác công nghiệp và hàm lâm đã cùng nhau phát triển những cái mà họ hi vọng sẽ là chuẩn cho hệ thống truyền thông điệp. Họ gọi nó là MPI (message passing interface) nghĩa là giao diện truyền thông điệp. MPI cung cấp những thủ tục trong một thư viện phục vụ cho thao tác truyền thông điệp và kết hợp. Khía cạnh cơ bản của MPI là nó định nghĩa một chuẩn đặc tả thư viện truyền thông điệp, đại diện cho một mô hình truyền thông điệp nhưng không phải là một đặc tả cho một trình biên dịch. MPI được đặc tả trong C, C++, Fortran 77 và dành cho máy tính song song, cụm máy tính (Cluster), và mạng không đồng nhất. MPI được thiết kế cho phép phát triển những thư viện phần mềm song song, cung cấp sự truy cập tới phần cứng song song tiên tiến. Ngày nay, truyền thông điệp là mô hình chuẩn cho lập trình song song.

MPI có một số lượng lớn các thủ tục( trên 120 thủ tục và đang được phát triển thêm), dù vậy chúng ta chỉ thảo luận một tập hợp con của nó. Phiên bản đầu tiên, được hoàn tất vào tháng 5 năm 1994 sau hai năm hội họp và thảo luận. Phiên bản đầu tiên bỏ qua một số cải tiến mà những cải tiến này được thêm vào phiên bản tiếp theo. Có một vài nâng cấp phiên bản 1.0 trong phiên bản 1.2. Phiên bản 2.0 được giới thiệu trong năm 1997 bao gồm tạo tiến trình động, những thao tác một phía và vào ra (I\O) song song.

Với một số lượng lớn các chức năng, MPI có thể được sử dụng để viết những ứng dụng với những đoạn mã hoàn hảo. Tuy vậy một chương trình cũng có thể được viết với một tập con của nó. Phần lớn các chương trình song song có thể được viết với chỉ 6 hàm cơ bản, đây là đề nghị của Group,Lusk, và Skjekkum(1990a) để thiết kế một chương trình song song thành công. Sử dụng những hàm cơ bản này ta có thể linh hoạt dùng chúng mà không cần làm chủ tất cả các thành phần của MPI để viết chương trình.

Trong luận văn này, xin giới thiệu hai trình thực thi miễn phí hổ trợ cho MPI: MPICH của phòng thí nghiệm Argonne National và đại học Misissippi dành cho Windows và một gói lập trình song song LAM/MPI sẵn có tích hợp trong Linux

được hỗ trợ bởi tổ chức LAM/MPI, chi tiết có thể tham khảo thêm tại địa chỉ www.lammpi.org , với hai môi trường lập trình khác nhau nhưng trong quá trình nghiên cứu và viết chương trình song song, tôi đã phối hợp chúng để có thể thiết kế các chương trình song song nhìn từ hai góc độ môi trường thực thi khác nhau.

Trong quá trình nghiên cứu, có những khó khăn như thiết lập mạng máy tính gồm các máy tính sử dụng hệ điều hành Linux, chúng ta có thể giải quyết bằng cách chuyển chương trình sang chạy trên mạng máy tính sử dụng hệ điều hành Windows bởi vì đây là môi trường có sẵn và đã quen thuộc với chúng ta. Mặt khác khi thiết kế chương trình song song, gỡ rối là chiếm nhiều thời gian nhất, có thể nhận thấy khi lập trình trên Linux thì dễ dàng gỡ rối hơn trên Windows do đó chúng ta có thể thiết kế chương trình trên Linux và chạy trên Windows.

Một phần của tài liệu Kỹ Thuật Đường Ống Và Cân Bằng Tải Trong Lập Trình Song Song MPI (Trang 41 - 49)