Cấu trúc Supervisor–Workers

Một phần của tài liệu Các hệ vi xử lý tiên tiến (Trang 75 - 81)

5.1 Môi trường PVM và cấu trúc ứng dụng

5.1.1 Cấu trúc Supervisor–Workers

Chỉ có một mức phân cấp trong cấu trúc này: một Supervisor và nhiều Workers.

Supervisor đóng vai trị là tác vụ khởi tạo được kích họat thủ cơng trên một trong những

máy chủ. Supervisor, cũng được gọi là master (chủ), có một số nhiệm vụ đặc biệt. Nó thường tương tác với người sử dụng, kích hoạt các worker trên các máy ảo, phân cơng công việc cho các worker , và thu thập kết quả từ các worker.

Các worker, còn được gọi là tớ, được kích hoạt bởi Supervisor để thực hiện các tính tốn. Các worker có thể độc lập hoặc khơng độc lập. Nếu chúng khơng độc lập, chúng có thể giao tiếp với nhau trước khi gửi kết quả tính tốn lại cho Supervisor.

Ví dụ, một ý tưởng đơn giản để sắp xếp một mảng số bằng cách sử dụng cấu trúc

Supervisor-worker có thể được mơ tả như sau. Supervisor tạo ra một số worker và chia các phần tử mảng cho họ sao cho mỗi worker nhận được số phần tử gần bằng nhau. Mỗi worker độc lập trong việc sắp xếp mảng của nó và gửi danh sách được sắp xếp trở lại cho Supervisor. Supervisor thu thập danh sách được sắp xếp từ các worker và kết hợp chúng thành một danh sách được sắp xếp. Hình 8.1 minh họa một ví dụ về sắp xếp một mảng phần tử sử dụng một Supervisor (S) và bốn worker (W1, W2, W3, và W4). Lưu ý rằng trong ví dụ này, các worker hoàn toàn độc lập và chỉ giao tiếp với Supervisor thực hiện thủ tục trộn trên bốn danh sách con được sắp xếp trong khi các worker vẫn còn rỗi.

(B) Supervisor rỗi và bốn worker đang sắp xếp các danh sách con của họ (D) Supervisor đang trộn bốn danh sách con được sắp xếp và bốn worker đang rỗi

Hình 8.1 Cấu trúc Supervisor-công nhân để sắp xếp dùng Supervisor S và bốn worker độc lập W1, W2, W3, và W4. Các cạnh liền nét cho thấy đường đi của tin nhắn. Các cạnh nét đứt giữa S và W1, W2, W3, và W4 chỉ ra rằng các worker được tạo ra bởi S.

Một cách phân loại danh sách khác sử dụng cấu trúc Supervisor-worker là tạo ra các worker giúp đỡ trong quá trình trộn và cuối cùng chỉ để Supervisor trộn hai danh sách con đã được sắp xếp. Hình 8.2 minh họa cách thức làm việc của thủ tục này sử dụng một Supervisor (S) và bốn worker (W1, W2, W3, và W4). Đầu tiên, Supervisor chia danh sách cho bốn worker. Mỗi worker sắp xếp danh sách con của họ một cách độc lập. Sau đó, các worker W2 và W4 gửi các danh sách con được sắp xếp của chúng tương ứng đến W1 và W3. Worker W1 sẽ trộn danh sách con được sắp xếp của nó với một danh sách nhận được từ W2. Tương tự như vậy, W3 sẽ hợp nhất danh sách con được sắp xếp của nó với một danh sách nhận được từ W4. Cuối cùng, Supervisor nhận được hai danh sách con được sắp xếp từ W1 và W3 để thực hiện khâu hợp nhất cuối cùng.

5.1.2 Cấu trúc phân cấp

Không giống như cấu trúc Supervisor-worker cấu trúc phân cấp cho phép các worker tạo ra những mức worker mới. Supervisor cấp cao là tác vụ khởi tạo, tạo ra một tập hợp worker ở cấp thứ hai. Những worker này có thể tạo ra các tập hợp worker khác

(B) Supervisor rỗi và bốn worker đang sắp xếp các danh sách con của họ (C) Các worker W2 và W4 gửi các danh sách đã được sắp xếp của họ đến W1 và W3 (D) Các worker W1 và W3 đang trộn hai danh sách con và W2 và W4 rỗi (E) Các worker W1 và W3 gửi hai danh sách con đã được sắp xếp đến Supervisor-worker ở mức tiếp theo, và v.v... (Một tác vụ tạo

ra tác vụ khác cũng được gọi là cha của nó.) Q trình tạo tác vụ này có thể tiếp tục ở bất kỳ cấp độ nào, hình thành nên cấu trúc cây. Lá của cây là những workerở mức thấp nhất. Cấu trúc này phù hợp rất tốt với cơ cấu của các ứng dụng chia để trị.

Ví dụ: Sắp xếp một mảng các phần tử dùng cấu trúc phân cấp có thể được thực hiện

như sau. Supervisor cao nhất tạo ra hai worker và giao cho họ một nửa mảng để sắp xếp. Sau đó, mỗi worker sẽ tạo ra hai worker mới và gửi cho mỗi người một nửa số mảng đã chia đơi để sắp xếp. Q trình này sẽ tiếp tục cho đến khi các worker lá có số phần tử thích hợp để sắp xếp. Các worker lá này sẽ sắp xếp danh sách của họ một cách độc lập và gửi danh sách này đến cha của chúng để thực hiện hoạt động hợp nhất (thao tác trộn). Quá trình này sẽ tiếp tục theo hướng đi lên cho đến khi cuối cùng Supervisor trên cùng trộn hai danh sách đã sắp xếp thành một mảng cuối cùng. Hình 8.3 minh họa thuật tốn sắp xếp bằng cách sử dụng cấu trúc phân cấp khi tám workerlá được sử dụng để sắp xếp. Chú ý rằng các cạnh nét đứt trong cây biểu diễn mối quan hệ cha-con giữa các tác vụ.

5.2 Tạo tác vụ

Một tác vụ trong PVM có thể được khởi động thủ cơng hoặc có thể nảy sinh từ tác vụ khác. Tác vụ ban đầu ln ln được kích hoạt thủ cơng đơn giản bằng cách chạy mã thực thi của nó trên một trong các host. Các tác vụ PVM khác có thể được tạo tự động từ trong các tác vụ khác. Hàm pvm_spawn () được sử dụng để tạo tác vụ động. Tác vụ gọi hàm pvm_spawn () được gọi là cha và các tác vụ mới được tạo ra được gọi là con. Để tạo ra một tác vụ con từ tác vụ cha đang chạy, ít nhất lập trình viên phải chỉ ra những điểm sau đây:

1. Máy mà trên đó tác vụ con được khởi động.

2. Đường dẫn đến tập tin thực thi trên máy được chỉ định. 3. Số bản sao của tác vụ con được tạo ra.

4. Một mảng các đối số của tác vụ con (s).

Vì tất cả các tác vụ PVM được xác định bởi một bộ định danh tác vụ nguyên, khi tác vụ được tạo ra nó được gán cho một bộ định danh duy nhất (TID). Việc xác định tác vụ có thể được sử dụng để chỉ ra những người gửi (bộ gửi, đối tương gửi) và người nhận (bộ nhận, đối tượng nhận) trong q trình truyền thơng. Chúng cũng có thể được sử dụng để ấn định các chức năng cho các tác vụ khác nhau dựa trên các TID của chúng.

5.2.1 Truy tìm bộ định danh tác vụ

Máy ảo song song cung cấp một số chức năng để truy tìm các giá trị TID để một tác vụ cụ thể có thể định danh chính nó, cha mẹ của nó, và các tác vụ khác trong hệ thống.

TID của tác vụ có thể truy tìm TID của riêng nó bằng cách gọi hàm PVM pvm_myid () PVM như sau:

* TID của tác vụ con (Child’s TID): Khi một tác vụ gọi hàm pvm_spawn function (), một

mảng chứa các TID của các tác vụ con được tạo ra bởi lời gọi này sẽ được trả lại. Ví dụ, mảng tid trong pvm_spawn () sau đây sẽ có các TID của tất cả các tác vụ con.

Pvm_spawn(…,…,…,…,…, &tid)

/ * Các TID của tác vụ con được tạo ra bởi lời gọi này được lưu trong mảng tid * / * TID

của tác vụ cha (Parent’s TID): Một tác vụ có thể truy tìm TID của tác vụ cha của nó (tác

vụ mà từ đó nó được sinh ra) bằng cách gọi hàm pvm_parent () như sau:

Giá trị PvmNoParent sẽ được trả về nếu tác vụ gọi là một tác vụ được tạo ra thủ cơng và khơng có tác vụ cha. Đây là một cách dễ dàng để phân biệt Supervisor với worker trong một ứng dụng.

TID của Daemon Một tác vụ có thể truy tìm TID của daemon đang chạy trên cùng một host khi một tác vụ khác có TID bằng id bằng cách gọi hàm pvm_tidtohost function () như sau:

H àm này rất có ích trong việc xác định host mà tác vụ đang chạy.

5.2.2 Tạo tác vụ động

Hàm pvm_spawn () được sử dụng để tạo một hoặc nhiều tác vụ trên cùng một máy hoặc các máy khác nhau trong cấu hình PVM. Định dạng của hàm này là:

Hàm này có sáu tham số và trả về số tác vụ được tạo ra thành công dưới dạng số thực trong biến num. Hai tham số đầu tiên là tên tập tin thực thi của chương trình được kích hoạt và các đối số được truyền qua thực thi (theo định dạng argv chuẩn, kết thúc với NULL).

Hai tham số tiếp theo cho biết nơi bắt đầu quá trình. Tham số flag điều khiển mục tiêu của phép tốn được tạo ra. Một giá trị khơng (zero) cho phép PVM quyết định máy nào thích hợp để bắt đầu tác vụ. Các giá trị khác xác định nơi tham số biểu thị tên máy, hoặc một loại kiến trúc. Chỉ định tên máy giúp lập trình viên kiểm sốt q trình phân cơng tác vụ. Chỉ định loại kiến trúc có thể thích hợp hơn trong một số trường hợp, đặc biệt khi các máy ảo được cấu tạo từ một tập hợp kiến trúc được phân tán rộng. Một trong những yêu cầu của lệnh được sinh ra là việc thực thi phải tồn tại sẵn trên bất kỳ máy nào nó đang chạy.

BẢNG 8.1 Các thơng số để tạo tác vụ động Tham số Ý nghĩa

Con Tên tệp thực thi của chương trình được bắt đầu. Quá trình thực thi phải nằm trên host mà nó chạy.

Đối số Một con trỏ hướng đến mảng đối số của chương trình. Nếu chương trình khơng lấy đối số nào con trỏ này sẽ là NULL.

Cờ Giá trị cờ bằng không cho phép hệ thống PVM quyết định máy nào sẽ chạy tác vụ được sinh ra. Các giá trị khác cho biết một tên host hoặc loại kiến trúc cụ thể được chỉ định để chạy các tác vụ được sinh ra. Ở đây tên host hoặc loại kiến trúc để chạy tác vụ được tạo ra phụ thuộc vào giá trị của cờ ở trên.

Howmany Số tác vụ con giống nhau được bắt đầu.

Tids Các TID của của tác vụ con được tạo ra bởi lời gọi này.

Hai tham số cuối cùng chứa thông tin điều khiển, chẳng hạn như số quá trình được sinh ra với lời gọi này, và một mảng để trả về thông tin, chẳng hạn như bộ định danh tác vụ và các mã lỗi. Các tham số khác nhau và ý nghĩa của chúng được tóm tắt trong bảng Bảng 8.1.

Ví dụ 1 Giả sử chúng ta muốn tạo ra hai và bốn bản sao của chương trình "worker(cơng nhân)" trên hai host tương ứng là: Homer và Fermi. Giả sử rằng các tập tin thực thi "worker" nằm trong thư mục "/ user / rewini" trong cả hai máy. Hai phát biểu sau đây trong tác vụ khởi tạo sẽ tạo ra các tác vụ cần thiết:

Tham số thứ hai bằng 0 khi khơng có đối số cho "worker(cơng nhân)". Tham số thứ ba là một loại cờ được sinh ra, được đặt là 1 để chúng ta có thể chỉ định Homer và Fermi như các host mục tiêu của chúng ta. Các giá trị TID của các tác vụ được tạo ra được trả về tid1 và tid2. Cuối cùng n1 và n2 là số tác vụ được tạo ra tương ứng trên homer và fermi.

5.3 Các nhóm tác vụ

PVM cho phép chạy các tác vụ thuộc các nhóm tên, các nhóm này có thể thay đổi tại bất kỳ thời điểm nào trong q trình tính tốn. Các nhóm rất hữu ích trong trường hợp khi một hoạt động tập thể chỉ được thực hiện trên một tập hợp con tác vụ. Ví dụ, một hoạt động phát tin, sẽ gửi một thông điệp tới tất cả các tác vụ trong một hệ thống, có thể sử dụng một nhóm có tên để gửi tin nhắn chỉ cho các thành viên của nhóm này. Một tác vụ có thể tham gia hoặc rời bỏ một nhóm tại bất kỳ thời điểm nào mà không cần thông báo cho các tác vụ khác trong nhóm. Một tác vụ cũng có thể thuộc nhiều nhóm. PVM cung cấp một số chức năng cho các tác vụ để tham gia và rời khỏi nhóm, và truy tìm thơng tin về các nhóm khác.

Một nhiệm vụ có thể tham gia một nhóm bằng cách gọi hàm pvm_joingroup() giống như sau: i = pvm_joingroup(group_name)

Chức năng này thêm tác vụ gọi nó đến nhóm có tên là group_name. Nó trả về số trường hợp của tác vụ vừa tham gia vào nhóm. Chính nhóm được tạo ra khi

pvm_joingroup được gọi lần đầu tiên. Trong trường hợp này, yếu tố gọi đầu tiên nhận giá

trị 0 làm số trường hợp. Số trường hợp được trả về bắt đầu tại 0 và tăng 1 mỗi khi tác vụ mới tham gia nhóm. Tuy nhiên, tập hợp số trường hợp này có thể có các khoảng trống do có một hoặc nhiều tác vụ rời khỏi nhóm. Khi một tác vụ tham gia nhóm với các khoảng trống trong tập hợp số trường hợp, thành viên mới này sẽ nhận được số trường hợp thấp nhất. Việc duy trì một tập hợp số trường hợp mà khơng có các khoảng trống là nhiệm vụ của lập trình viên.

Một thành viên của nhóm có thể rời khỏi nhóm bằng cách gọi hàm pvm_lvgroup() như sau: Info = pvm_lvgroup(group_name)

Tác vụ gọi thành cơng hàm này sẽ rời khỏi nhóm GROUP_NAME. Trong trường hợp có lỗi, info sẽ có giá trị âm. Nếu tác vụ này quyết định gia nhập lại nhóm này tại một thời điểm sau đó, nó có thể nhận được một số trường hợp khác bởi vì số cũ đã được ấn định cho một tác vụ khác có thể đã tham gia.

Có một số hàm khác có thể được gọi bởi bất kỳ tác vụ nào để truy tìm thơng tin mà khơng cần phải là thành viên của nhóm cụ thể. Ví dụ, hàm pvm_gsize () có thể được sử dụng để truy tìm kích thước của một nhóm. Nó chọn đầu vào là tên nhóm và trả về số thành viên trong nhóm. Hàm pvm_gettid () có chức năng truy tìm TID của một tác vụ ứng với số trường hợp và tên nhóm của nó. Tương tự, hàm pvm_getinst () truy tìm thơng tin về số trường hợp của một tác vụ ứng với TID và tên nhóm của nó.

Ví dụ 2: Giả sử rằng tác vụ T0, T1, T2, và T3 có các TID tương ứng là 200, 100, 300,

và 400. Chúng ta hãy xem điều gì xảy ra sau khi thực thi mỗi phát biểu sau đây.

1. Tác vụ T0 gọi hàm i1 = pvm_joingroup ("slave") slave: tớ nhóm "slave" được tạo ra, T0 tham gia nhóm này và T0 được ấn định số trường hợp là 0 (i1 = 0).

2. Tác vụ T1 gọi hàm i2 = pvm_joingroup ("slave") T1 tham gia nhóm "slave" và được ấn định số trường hợp 1 (i2 = 1).

3. Tác vụ T2 gọi hàm i3 = pvm_joingroup ("slave") T2 tham gia nhóm "slave" và được ấn định số trường hợp 2 (i3 = 2).

4. Tác vụ T1 gọi hàm info = pvm_lvgroup ("slave") T1 rời khỏi nhóm "slave" và số trường hợp 1 sẽ có sẵn cho các tác vụ khác muốn tham gia vào nhóm "slave" trong tương lai.

5. Một số tác vụ gọi hàm size = pvm_gsize ("slave") Kích thước biến sẽ được gán giá trị 2, đó là số tác vụ hiện tại thuộc nhóm "slave".

6. Tác vụ T3 gọi hàm I4 = pvm_j oingroup ("slave"T3 tham gia nhóm "slave" và được gán số trường hợp 1 (I4 = 1).

7. Tác vụ T1 gọi hàm i5 = pvm_j oingroup ("slave") T1 gia nhập lại nhóm "slave" và hiện đang được gán số trường hợp 3 (i5 = 3).

8. Một số tác vụ gọi hàm tid = pvm_gettid ("slave", 1) biến tid sẽ được gán giá trị 400, đó là TID của tác vụ T3 mà số trường hợp của nó có thể bằng 1.

9. Một số tác vụ gọi hàm inst = pvm_getinst ("slave", 100) Biến inst sẽ được gán giá trị 3, đây là số trường hợp của tác vụ T1 mà TID của nó bằng 100.

Một phần của tài liệu Các hệ vi xử lý tiên tiến (Trang 75 - 81)