Tinh toan luat va luat ly thuyet do thi
Transcript of Tinh toan luat va luat ly thuyet do thi
TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN
KHOA CÔNG NGHỆ THÔNG TIN
BỘ MÔN CÔNG NGHỆ PHẦN MỀM
HUỲNH BÁ THANH TÙNG - 0112079
TRẦN VIỆT CƯỜNG - 0112339
NGHIÊN CỨU TÍNH TOÁN LƯỚI VÀ
THỬ NGHIỆM MỘT SỐ THUẬT TOÁN
LÝ THUYẾT ĐỒ THỊ
KHÓA LUẬN CỬ NHÂN TIN HỌC
GIÁO VIÊN HƯỚNG DẪN
TS. TRẦN ĐAN THƯ
Th.S NGUYỄN THANH SƠN
NIÊN KHÓA 2001-2005
NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
NHẬN XÉT CỦA GIÁO VIÊN PHẢN BIỆN
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
..........................................................................................................................................
LỜI CẢM ƠN
Chúng em xin bày tỏ lòng biết ơn chân thành nhất đến thầy Trần Đan
Thư và thầy Nguyễn Thanh Sơn, hai thầy đã tận tâm hướng dẫn, giúp đỡ chúng
em trong suốt thời gian thực hiện luận văn này.
Chúng con xin gửi tất cả lòng biết ơn sâu sắc và sự kính trọng đến ông
bà, cha mẹ, cùng toàn thể gia đình, những người đã nuôi dạy chúng con trưởng
thành đến ngày hôm nay.
Chúng em cũng xin chân thành cám ơn quý Thầy cô trong Khoa Công
nghệ thông tin, trường Đại học Khoa học Tự nhiên Tp.Hồ Chí Minh đã tận tình
giảng dạy, hướng dẫn, giúp đỡ và tạo điều kiện cho chúng em thực hiện tốt
luận văn này.
Xin chân thành cám ơn sự giúp đỡ, động viên và chỉ bảo rất nhiệt tình
của các anh chị và tất cả các bạn, những người đã giúp chúng tôi có đủ nghị lực
và ý chí để hoàn thành luận văn này.
Mặc dù đã cố gắng hết sức, song chắc chắn luận văn không khỏi những
thiếu sót. Chúng em rất mong nhận được sự thông cảm và chỉ bảo tận tình của
quý Thầy Cô và các bạn.
TP.HCM, 7/2005
Nhóm sinh viên thực hiện
Huỳnh Bá Thanh Tùng - Trần Việt Cường
LỜI NÓI ĐẦU
Nhân lọai ngày nay đang chứng kiến sự phát triển mạnh mẽ của ngành
Công nghệ Thông tin, một trong những ngành mũi nhọn của nhiều quốc gia
trên thế giới. Sự phát triển vượt bậc của nó là kết quả tất yếu của sự phát triển
kèm theo các thiết bị phần cứng cũng như phần mềm tiện ích.
Sự phát triển đó đã kéo theo rất nhiều các ngành khác phát triền theo,
trong đó có lĩnh vực nghiên cứu khoa học. Tuy công nghệ ngày càng phát triển,
tốc độ xử lý của các thiết bị cũng không ngừng tăng cao, nhưng nhu cầu tính
toán của con người vẫn còn rất lớn. Cho đến hiện nay vẫn còn rất nhiều vấn đề
mà các nhà khoa học cùng với khả năng tính toán của các máy tính hiện nay
vẫn chưa giải quyết được hay giải quyết được nhưng với thời gian rất lớn.
Các vấn đề đó có thể là :
• Mô hình hóa và giả lập
• Xử lý thao tác trên các dữ liệu rất lớn
• Các vấn đề “grand challenge” (là các vấn đề không thể giải quyết
trong thời gian hợp lý)
Lời giải cho những vấn đề này đã dẫn đến sự ra đời của các thế hệ siêu
máy tính. Tuy nhiên việc đầu tư phát triển cho các thiết bị này gần như là điều
quá khó khăn đối với nhiều người, tổ chức, trường học…. Chính vì lẽ đó mà
ngày nay người ta đang tập trung nghiên cứu cách cách sử dụng các tài nguyên
phân bố một cách hợp lý để tận dụng được khả năng tính toán của các máy tính
đơn. Những giải pháp này được biết đến với nhiều tên gọi khác nhau như meta-
computing, salable-computing, global- computing, internet computing và gần
nhất hiện nay là peer to peer computing hay Grid computing.
Đây là phương pháp nhằm tận dụng khả năng của các máy tính trên toàn
mạng thành một máy tính “ảo” duy nhất, nhằm hợp nhất tài nguyên tính toán ở
nhiều nơi trên thế giới để tạo ra một khả năng tính toán khổng lồ, góp phần giải
quyết các vấn đề khó khăn trong khoa học và công nghệ. Ngày nay nó đang
càng được sự hỗ trợ mạnh hơn của các thiết bị phần cứng, băng thông…
Grid Computing có khả năng chia sẻ, chọn lựa, và thu gom một số lượng
lớn những tài nguyên khác nhau bao gồm những siêu máy tính, các hệ thống
lưu trữ, cùng với những nguồn dữ liệu, các thiết bị đặt biệt… Những tài nguyên
này được phân bố ở các vùng địa lý khác nhau và thuộc về các tổ chức khác
nhau.
Nhận thấy được nhu cầu phát triển ấy, nhóm chúng em đã quyết định
chọn thực hiện đề tài “Nghiên cứu tính toán lưới và thực nghiệm trên một
số thuật toán lý thuyết đồ thị”
Mục tiêu của đề tài đề ra là tìm hiểu về tính toán lưới, và qua đó tận
dụng các kiến thức có được để có thể cài đặt một số thuật toán lý thuyết đồ thị,
nhằm có thể giải quyết các vấn đề tìm đường đi khi số đỉnh tương đối lớn…
Các nội dung chính:
• Nghiên cứu tính toán lưới
• Tìm hiểu các môi trường hỗ trợ
• Tìm hiểu lập trinh song song và phân tán
• Cài đặt một số thuật toán với kiến thức có được
Nội dung của luận văn được chia làm 6 chương :
Chương 1. Giới thiệu : Giới thiệu tổng quan về tính toán lưới, khái
niệm lịch sử phát triển.
Chương 2. Tính toán song song và phân bố : Trình bày về các kiến
trúc, mô hình xử lý song song và phân bố, cách thức xây dựng chương trình,
thiết kế thuật toán…
Chương 3. Các môi trường hỗ trợ tính toán lưới : Tìm hiểu về các
môi trường đang được sử dụng và nghiên cứu hiện nay trên thế giới.
Chương 4. Mô hình lập trình truyền thông điệp - MPI : Mô hình cụ
thể được dùng để phát triển ứng dụng MPI.
Chương 5. Thử nghiệm các thuật toán lý thuyết đồ thị : Cách thức
xây dựng chương trình , các khái niệm lý thuyết, thực nghiệm thực tế …
Chương 6. Tổng kết : Nêu các kết quả đã đạt được, một số vấn đề còn
tồn tại, định hướng mục tiêu mở rộng phát triển đề tài trong tương lai.
Mục lục Danh sách hình..................................................................................................... 11
Chương 1. Giới thiệu ........................................................................................... 13
1.1. Các khái niệm.......................................................................................... 13
1.2. Những thách thức đối với tính toán lưới ................................................. 16
Chương 2. Tính toán song song và phân bố ...................................................... 17
2.1. Khái niệm ................................................................................................ 17
2.2. Nền tảng tính toán song song và phân bố ............................................... 18
2.2.1. Kiến trúc xử lý song song và phân bố ..............................................18
2.2.2. Tổ chức vật lý của các nền tảng song song và phân bố ....................25
2.3. Một số mô hình lập trình song song thông dụng..................................... 26
2.3.1. Mô hình chia sẽ không gian bộ nhớ..................................................26
2.3.2. Mô hình truyền thông điệp ...............................................................27
2.4. Cách thức xây dựng một chương trình song song và phân bố ................ 29
2.4.1. Các thuật ngữ căn bản.......................................................................29
2.4.2. Thiết kế thuật toán song song ...........................................................31
2.4.3. Một số phương pháp tối ưu...............................................................43
2.4.4. Các mô hình thuật toán song song....................................................48
Chương 3. Các môi trường hỗ trợ tính toán lưới ............................................. 52
3.1. Giới thiệu................................................................................................. 52
3.2. Các vấn đề khi lập trình luới ................................................................... 53
3.2.1. Tính mang chuyển, tính khả thi và khả năng thích ứng....................53
3.2.2. Khả năng phát hiện tài nguyên .........................................................54
3.2.3. Hiệu năng..........................................................................................54
3.2.4. Dung lỗi ............................................................................................55
3.2.5. Bảo mật .............................................................................................55
3.2.6. Các siêu mô hình...............................................................................55
3.3. Tổng quát về các môi trường hỗ trợ........................................................ 56
3.3.1. Một số môi trường Grid....................................................................56
3.3.2. Những mô hình lập trình và công cụ hỗ trợ......................................59
3.3.3. Môi trường cài đặt ............................................................................64
3.4. Những kỹ thuật nâng cao hỗ trợ lập trình ............................................... 75
3.4.1. Các kỹ thuật truyền thống.................................................................76
3.4.2. Các kỹ thuật hướng dữ liệu...............................................................76
3.4.3. Các kỹ thuật suy đoán và tối ưu........................................................77
3.4.4. Các kỹ thuật phân tán........................................................................77
3.4.5. Nhập xuất hướng Grid ......................................................................78
3.4.6. Các dịch vụ giao tiếp cấp cao ...........................................................78
3.4.7. Bảo mật .............................................................................................80
3.4.8. Dung lỗi ............................................................................................80
3.4.9. Các siêu mô hình và hệ thống thời gian thực hướng Grid................82
3.5. Tóm tắt .................................................................................................... 83
Chương 4. Mô hình lập trình truyền thông điệp - MPI................................... 85
4.1. Các khái niệm cơ bản .............................................................................. 86
4.2. Cấu trúc chương trình MPI ..................................................................... 89
4.3. Trao đổi thông tin điểm-điểm ................................................................. 90
4.3.1. Các thông tin của thông điệp ............................................................90
4.3.2. Các hình thức truyền thông...............................................................91
4.3.3. Giao tiếp blocking.............................................................................92
4.3.4. Giao tiếp non-blocking .....................................................................96
4.4. Trao đổi thông tin tập hợp..................................................................... 101
4.4.1. Đồng bộ hóa....................................................................................101
4.4.2. Di dời dữ liệu trong nhóm ..............................................................101
4.4.3. Tính toán gộp ..................................................................................105
4.5. Các kiểu dữ liệu..................................................................................... 109
4.5.1. Những kiểu dữ liệu đã được định nghĩa .........................................109
4.5.2. Các kiểu dữ liệu bổ sung.................................................................110
4.5.3. Pack và UnPack ..............................................................................113
Chương 5. Thử nghiệm các thuật toán lý thuyết đồ thị ................................. 114
5.1. Các khái niệm cơ bản ............................................................................ 114
5.2. Dijkstra .................................................................................................. 115
5.2.1. Tuần tự ............................................................................................115
5.2.2. Song song........................................................................................119
5.2.3. Thực nghiệm chương trình .............................................................120
5.3. Prim ....................................................................................................... 122
5.3.1. Tuần tự ............................................................................................122
5.3.2. Song song........................................................................................124
5.3.3. Thực nghiệm chương trình .............................................................126
5.4. Bellman – Ford...................................................................................... 128
5.4.1. Tuần tự ............................................................................................128
5.4.2. Song song........................................................................................130
5.4.3. Thực nghiệm chương trình .............................................................132
5.5. Đánh giá chung...................................................................................... 134
Chương 6. Tổng kết ........................................................................................... 136
6.1. Kết luận ................................................................................................. 136
6.2. Hướng phát triển ................................................................................... 136
Tài liệu tham khảo ............................................................................................. 138
Danh sách hình
Hình 1-1 : 3 tầng của Grid ................................................................................ 15
Hình 2-1 : Phân lọai hệ thống máy tính theo Flynn-Johnson ........................... 19
Hình 2-2 : Kiến trúc SISD ................................................................................ 19
Hình 2-3 : Kiến trúc SIMD ............................................................................... 20
Hình 2-4 : Kiến trúc MISD ............................................................................... 22
Hình 2-5 : Kiến trúc MIMD.............................................................................. 23
Hình 2-6 : Mô hình chía sẽ không gian bộ nhớ ................................................ 27
Hình 2-7 : Mô hình truyền thông điệp .............................................................. 28
Hình 3-1 : Mô hình NetSolve............................................................................ 56
Hình 3-2 : Các thành phần của Globus ............................................................. 59
Hình 4-1 : Các tiến trình tạo lập trên mô hình lập trình MPI ........................... 86
Hình 4-2 : Cách thức truyền thông của các process.......................................... 87
Hình 4-3 : Blocking và non-blocking ............................................................... 88
Hình 4-4 : Group, communicator và rank......................................................... 88
Hình 4-5 : Cấu trúc của chương trình MPI ....................................................... 89
Hình 4-6 : Giao tiếp blocking ........................................................................... 92
Hình 4-7 : Thứ tự các xử lý............................................................................... 95
Hình 4-8 : Cách thức xử lý tiến trình ................................................................ 95
Hình 4-9 : Giao tiếp non-blocking .................................................................... 96
Hình 4-10 : Broadcast dữ liệu ......................................................................... 102
Hình 4-11 : Ví dụ hàm Scatter ........................................................................ 103
Hình 4-12 : Hàm MPI_Gather ........................................................................ 103
Hình 4-13 : Hàm MPI_Allgather .................................................................... 104
Hình 4-14 : Hàm MPI_Alltoall ....................................................................... 104
Hình 4-15 : Hàm MPI_Reduce ....................................................................... 105
Hình 4-16 : Sử dụng 8 xử lý để tính giá trị tuyệt đối...................................... 107
Hình 4-17 Hàm Mpi-Allreduce....................................................................... 108
Hình 4-18 : Hàm MPI_Reduce_scatter........................................................... 108
Hình 4-19 : Hàm MPI_Scan ........................................................................... 109
Hình 4-20 : MPI_Type_contiguous ................................................................ 110
Trang 12
Hình 4-21 : MPI_Type_vetor.......................................................................... 111
Hình 4-22 : MPI_Type_indexed ..................................................................... 112
Hình 4-23 : MPI_Type_struct ......................................................................... 112
Hình 5-1. Thuật toán Dijkstra tuần tự ............................................................. 118
Hình 5-2 : Thuật toán Dijkstra song song....................................................... 119
Hình 5-3. Thuật toán Prim tuần tự .................................................................. 124
Hình 5-3 : Thuật toán Prim song song ............................................................ 125
Hình 5-4: Thuật toán Bellman-Ford tuần tự ................................................... 130
Hình 5-5 : Thuật toán Bellman-Ford song song ............................................. 132
Trang 13
Chương 1. Giới thiệu
1.1. Các khái niệm
Trong những năm đầu thập niên 90, nhiều nhóm nghiên cứu đã bắt đầu
khai thác các nguồn tài nguyên tính toán phân tán trên Internet. Các nhà khoa
học đã tập trung và sử dụng hàng trăm các máy trạm để thực hiện các chương
trình song song như thiết kế phân tử và hiển thị đồ họa máy tính. Trong khi đó
các nhóm nghiên cứu khác đã kết hợp các siêu máy tính lớn lại với nhau thành
một siêu máy tính ảo duy nhất, rồi phân phối các phần của một ứng dụng rất
lớn cho các máy tính trên một mạng diện rộng, ví dụ như máy tính giả lập các
ứng dụng tương tác giữa chất lỏng và cánh quạt của chân vịt tàu…Thêm vào đó
phạm vi của các dự án nghiên cứu này đã nêu ra tiềm năng thực sự của mạng
máy tính, cùng với cơ sở phần mềm và tin học để phát triển nó xa hơn.
Hệ thống đa bộ xử lý (Multiprocessor Systems - MPs), Cluster, Grids là
các ví dụ của kiến trúc tính toán phân tán. Trong MPs, các bộ xử lý được kết
hơp chặt chẽ với nhau, thông qua bộ nhớ chia sẽ chung và đường truyền kết nối
rất cao. Ví dụ như là PVPs (Parallel Vector Processors), chúng hầu như rất
thích hợp cho tính toán hiệu năng cao, như là các ứng dụng song song dựa vào
trao đổi thông điệp tốc độ cao giữa các tiến trình song song.
Trang 14
Trong khi đó Cluster lại là các máy tính đơn hay đa bộ xử lý được kết
hợp tương đối với nhau thông qua đường mạng, vì thế nó chậm hơn từ 1 đến 2
lần so với kết nối MP. Ví dụ như cluster Beowulf chạy Linux, hay TCF
(Technical Compute Farm) của Sun chạy hệ điều hành Solaris/TM, chúng được
sử dụng cho các tính toán số lượng lớn, phân phối các tác vụ tính toán (thường
là không song song) cho các bộ xử lý, rồi thu thập lại các kết quả tính toán vào
kết quả toàn cục. Các tính toán này có thể là việc hiển thị hàng ngàn khung
hình để làm phim hay là giả lập việc kiểm tra và thiết kế để xây dựng thế hệ
tiếp theo của chip VLSI, hay như trong công nghệ sinh học, đó là việc cắt lớp
hàng trăm ngàn chuỗi gen.
Trong khi MPs và Cluster chỉ là các hệ thống đơn, thường là trong một
domain đơn. Grid điện toán bao gồm các cluster của mạng các MPs hay/và
cluster, nằm trên nhiều domain khác nhau, phân bố ở nhiều phòng ban, xí
nghiệp hay thậm chí là trên mạng Internet. Về bản chất, những grid có một độ
phức tạp cao hơn, đặc biệt là ở tầng trung gian, trong việc thực thi, quản lý, và
sử dụng các tài nguyên tính toán phân tán, và ở tầng ứng dụng là việc thiết kế,
phát triển, chạy các phần mềm để triển khai grid một cách hiệu quả.
Tóm lại Grid là một kiến trúc tính toán phân tán cho phép chuyển giao
các tài nguyên lưu trữ và tính toán như thể là một dịch vụ trên Internet. Đây là
bước phát triển tiếp theo về cơ sở hạ tầng kỹ thuật, cho phép kết nối các máy
tính phân tán, các thiết bị lưu trữ, các thiết bị di động, các công cụ, cơ sở dữ
liệu, và các ứng dụng phần mềm, và cung cấp cách thức truy cập duy nhất đến
cộng đồng người dùng để cho phép tính toán, trao đổi thông tin và cộng tác.
Một số hệ thống grid hiện tại như là NASA Information Power Grid (IPG);
DoD Distance Computing và NetSolve cho chia sẽ và khai thác phần mềm toán
học; Nimrod cho chia sẽ tài nguyên trên phạm vi trường học; SETI@Home cho
tìm kiếm trí thông minh ngòai trái đất; hay là APGrid để kết nối các trung tâm
máy tính ở vành đai Châu Á Thái Bình Dương trong tương lai gần.
Trang 15
Hình 1-1 : 3 tầng của Grid
Grid là một cơ sở hạ tầng về phần cứng lẫn phần mềm cung cấp truy cập
phụ thuộc, thích hợp, rộng khắp và chi phí thấp vào các khả năng tính toán.
Trong một tương lai không xa, những grid này sẽ được các kỹ sư, nhà khoa
học, khoa học thực nghiệm, công ty, tổ chức, môi trường, giáo dục và đào tạo,
khách hàng, … sử dụng rộng rãi. Chúng sẽ được dành riêng cho tính toán theo
yêu cầu, tính toán trên thông tin nhạy cảm, tính toán cộng tác, và siêu tính toán,
dựa trên cơ sở của khách hàng/nhà cung cấp.
Ngày nay chúng ta đang thấy những nỗ lực đầu tiên nhằm khai thác một
cách có hệ thống các nguồn tài nguyên tính toán lưới trên mạng Internet.
Những dự án này được gọi là peer-to-peer computing, như SETI@home,
Distributed.Net và Folderol, cho phép người dùng Internet tải về các dữ liệu
khoa học, chạy trên các máy cá nhân theo chu trình xử lý chia sẽ, và gửi lại kết
quả cho cơ sở dữ liệu trung tâm. Gần đây có một dự án ở một trường đại học,
được gọi là Compute Power Market, được xây dựng nên nhằm phát triển các kỹ
thuật phần mềm cho phép tạo lập những Grid, mà ở đó bất cứ ai cũng có thể
mua hay bán khả năng khả năng tính toán giống như cách mà người ta sử dụng
điện hiện nay.
Trang 16
1.2. Những thách thức đối với tính toán lưới
Hầu hết các kỹ thuật phức tạp bên dưới dành cho Grid hiện nay đang
được tiếp tục phát triển. Các môi trường Grid mẫu tồn tại giống như các dự án
Globus và Legion. Đồ án EcoGrid thì đang nghiên cứu cách thức quản lý tài
nguyên, và các khối xây dựng như vậy đang tồn tại trong trình quản lý tài
nguyên mang tính thương mại của phần mềm Sun Grid Engine.
Diễn đàn Grid (GGF – Global Grid Forum), được thành lập vào năm
1998, đã tập hợp được hàng trăm các nhà khoa học để cùng nhau nghiên cứu và
thảo luận về một kiến trúc Grid chung. Trong đó vẫn còn tồn tại một số thách
thức sau:
• Phát triền phần mềm ứng dụng cho Grid
• Chỉ ra và truy cập các nguồn tài nguyên tính toán thích hợp trên môi
trường phân tán
• Định nghĩa những giao tiếp chuẩn cho phép giao tiếp giữa các khối
Grid với nhau, nhằm đáp ứng nhu cầu phát triển ứng dụng.
• Bảo đảm các truy cập được xác nhận và truyền dữ liệu an toàn.
• Cung cấp các dịch vụ cho phép theo dõi, quảng cáo và kết xuất báo
cáo.
• Thiết kế các nghi thức mạng cho việc trao đổi và định dạng thông
điệp.
Trang 17
Chương 2. Tính toán song song và phân bố
2.1. Khái niệm
Ngày nay trong khi công nghệ ngày một phát triển thì nhu cầu về tốc độ
tính toán của các hệ thống máy tính cũng ngày một tăng cao. Các lĩnh vực đòi
hỏi tính tóan hiệu năng cao như là mô hình số và giả lập các vấn đề của khoa
học và công nghệ.
Ngoài ra nó còn nhằm giải quyết các lọai vấn đề cần tốc độ xử lý cao
như:
• Mô hình hóa và giả lập
Mô hình các mẫu DNA
Mô hình hóa chuyển động của các phi hành gia
…
• Xử lý/Thao tác trên các dữ liệu rất lớn
Xử lý ảnh và tín hiệu
Khai thác dữ liệu và cơ sở dữ liệu
Xác định địa chấn
…
• Các vấn đề “grand challenge” (là những vấn đề không thể giải quyết
trong thời gian “hợp lý”, như cần 100, 1000,…năm để có đáp án)
Mô hình khí hậu
Sự chuyển động của chất lỏng
Bộ gene con người
Mô hình chất bán dẫn
…
Xuất phát từ nhu cầu đó đã dẫn đến sự cần thiết phải có những hệ thống
song song và phân bố nhằm tận dụng tối đa khả năng thực thi của các bộ xử lý,
và để giải quyết các vấn đề nan giải trên.
Trang 18
2.2. Nền tảng tính toán song song và phân bố Trong phần này chúng ta sẽ xem xét cách tổ chức logic và vật lý của các
nền tảng song song và phân tán. Cách tổ chức logic liên quan đến quan điểm
của người lập trình (kiến trúc xử lý song song và phân bố) trong khi cách tổ
chức vật lý liên quan đến cách cơ cấu thực sự của các phần cứng bên dưới.
Trong tính toán song song thì từ quan điểm của người lập trình gồm 2 thành
phần chính quan trọng đó là cách thức thể hiện các tác vụ song song (cấu trúc
điều khiển) và những phương pháp xác định tương tác giữa các tác vụ này (mô
hình giao tiếp).
2.2.1. Kiến trúc xử lý song song và phân bố Máy tính song song có thể được chia theo 2 lọai chính là : dòng điều
khiển (control flow) và dòng dữ liệu (data flow). Máy tính song song dòng điều
khiển dựa chủ yếu theo các nguyên tắc của máy tính Von Neumann, ngọai trừ
nhiều dòng điều khiển có thể thực hiện vào bất cứ thời gian nào. Máy tính song
song dòng dữ liệu , đôi khi được biết đến là “phi Von Neumann”, thì hoàn toàn
khác biệt ở chỗ nó không có con trỏ trỏ tới các chỉ thị hiện hành hay trung tâm
điều khiển. Ở đây chúng ta chỉ tập trung vào các máy tính song song dòng điều
khiển.
Năm 1966, M.J.Flynn đã phân chia các hệ thống máy tính dựa trên dòng
chỉ thị và dòng điều khiển thành 4 loại sau:
• SISD (Single Instruction stream, a Single Data stream)
• SIMD (Single Instruction stream, Multiple Data streams)
• MISD (Multiple Instruction streams, a Single Data stream)
• MIMD (Multiple Instruction streams, Multiple Data streams)
Phân theo mức độ hay được sử dụng:
MIMD > SIMD > MISD
Trang 19
Inst
ruct
ion
Stre
am(s
) SISD(Uniprocessors)
SIMD(Array Processors)
MISD
GMSV GMMP
DMSV
Data Stream(s)Single Multiple
Mul
tiple
Sin
gle
Shared Variables Message Passing
Glo
bal
Dis
tribu
ted
Mem
ory
Communication
DMMP
MIMD
Hình 2-1 : Phân lọai hệ thống máy tính theo Flynn-Johnson
2.2.1.1. SISD
Hình 2-2 : Kiến trúc SISD
Kiến trúc này tương tự với kiến trúc Von Neumann. Một đơn vị điều
khiển tiếp nhận một chỉ thị đơn từ bộ nhớ, sau đó đưa vào cho bộ xử lý thực thi
trên một đơn vị dữ liệu được chỉ ra trong chỉ thị nhận được, và cuối cùng là đưa
kết quả nhận được vào bộ nhớ.
2.2.1.2. SIMD
Hầu hết các máy tính song song ban đầu đều được thiết kế theo kiến trúc
SIMD. Trong kiến trúc này, một đơn vị xử lý trung tâm sẽ thông dịch và quảng
bá các tín hiệu điều khiển thích hợp cho các bộ xử lý theo chiều kim đồng hồ.
Từng bộ xử lý sẽ thực thi các chỉ thị một cách đồng thời, và chúng cũng có
quyền không tiếp nhận trên các chỉ thị nào đó. Sự phổ biến của kiến trúc SIMD
là do tính năng của các ứng dụng song song ban đầu và từ yêu cầu của nền kinh
Trang 20
tế. Theo quan điểm của người dùng thì các ứng dụng sử dụng kiến trúc SIMD
thì dễ dàng được lập trình hơn và tận dụng hiệu quả hơn các thiết bị phần cứng.
Hình 2-3 : Kiến trúc SIMD
Bên trong SIMD, tồn tại hai lựa chọn thiết kế cơ bản sau:
1. SIMD đồng bộ và bất đồng bộ. Trong một máy SIMD, từng bộ xử
lý có thể thực thi hay bỏ qua các chỉ thị được quảng bá dựa vào trạng
thái cục bộ của nó hay những điều kiện phụ thuộc vào dữ liệu. Tuy
nhiên điều này có thể dẫn đến xử lý một vài tính toán điều kiện
không hiệu quả. Một cách giải quyết khả thi là sử dụng phiên bản bất
đồng bộ của S1IMD, được biết đến là SPMD (Single Program
Multiple Data), trong đó từng bộ xử lý sẽ chạy một bản sao của
Trang 21
chương trình chung. Điểm thuận lợi của SPMD là trong lúc tính toán
biểu thức điều kiện “if-then-else”, từng bộ xử lý sẽ chỉ thực hiện ở
nhánh thích hợp mà không mất thời gian cho các chi phí tính toán
khác.
2. Chip SIMD tùy chọn hay thống nhất (commodity). Một máy
SIMD có thể được thiết kế dựa trên những thành phần thống nhất
hay là từ những con chip tùy chọn. Trong cách tiếp cận thứ nhất thì
các thành phần có xu hướng rẻ hơn do sản xuất hàng loạt. Tuy nhiên
những thành phần mang mục đích chung như vậy có thể chứa các
yếu tố không cần thiết cho một thiết kế cụ thể nào đó. Những thành
phần thêm vào có thể làm phức tạp việc thiết kế, sản xuất và kiểm
thử các máy SIMD và cũng có thể đem lại khiếm khuyết về tốc độ
xử lý. Còn các thành phần tùy chọn thì nhìn chung hỗ trợ tốt hơn cho
thực thi tuy nhiên nó cũng dẫn đến chi phí cao hơn cho việc phát
triển. Khi việc tích hợp nhiều bộ xử lý cùng với bộ nhớ dư dật trên
một con chip VLSI đơn trở nên khả thi, thì việc kết hợp ưu điểm của
2 cách tiếp cận trên là hoàn toàn có thể. 2.2.1.3. MISD
Mô hình này hầu như không thấy nhiều trong các ứng dụng. Một trong
những lý do là bởi vì hầu hết các ứng dụng không thế áp dụng một cách dễ
dàng vào kiến trúc MISD, điều này dẫn đến việc thiết kế ra một kiến trúc để
thỏa mãn cho một mục đích chung là điều không thể. Tuy nhiên có thể áp dụng
các bộ xử lý song song kiểu MISD vào trong một ứng dụng cụ thể nào đó.
Trang 22
Hình 2-4 : Kiến trúc MISD
Trong hình trên là ví dụ về một bộ xử lý song song với kiến trúc MISD.
Một dòng dữ liệu đơn đi vào một máy tính gồm 5 bộ xử lý. Nhiều phép biến
đổi được thực hiện trên từng đơn vị dữ liệu trước khi nó được chuyển sang một
(hay nhiều) bộ xử lý khác. Các đơn vị dữ liệu kế tiếp có thể đi qua các phép
biến đổi khác do điều kiện độc lập dữ liệu của các dòng chỉ thị hay do các thẻ
điều khiển đặc biệt được truyền cùng với dữ liệu. Chính vì vậy mà cách tổ chức
theo kiến trúc MISD có thể được xem như là một hệ thống ống lệnh cấp độ cao
và phức tạp với nhiều đường dẫn và trong đó từng giai đọan có thể được lập
trình riêng biệt.
2.2.1.4. MIMD
Được tiên đoán bởi các doanh nghiệp vào thập niên 90, mô hình MIMD
gần đây đã trở nên khá phổ biến. Lý do cho sự thay đổi này là vì tính uyển
chuyển cao của kiến trúc MIMD và bởi khả năng tận dụng được những ưu
điểm của các bộ vi xử lý được sản xuất hàng lọat (commodity
microprocessors), vì thế tránh được những vòng phát triển dài dòng và qua đó
có thể được phát triển cùng với sự cải thiện của các bộ xử lý. Các máy tính
MIMD được áp dụng rất hiệu quả cho các ứng dụng song song mà vấn đề của
nó được phân rã từ trung bình cho đến tốt (medium- to coarse-grain parallel
applications).Ưu điểm của các máy tính MIMD bao gồm khả năng uyển
Trang 23
chuyển cao trong việc khai thác nhiều dạng thức song song khác nhau, dễ phân
chia nhỏ hơn cho các bộ xử lý độc lập trong môi trường đa người dùng (tính
chất này là ngụ ý quan trọng cho tính dung lỗi), ít khó khăn trong việc mở rộng
(scalability). Nhưng bên cạnh đó kiến trúc này cũng có khuyết điểm là sự quá
tải do giao tiếp giữa các bộ xử lý và việc lập trình gặp nhiều khó khăn.
Hình 2-5 : Kiến trúc MIMD
Bên trong kiến trúc MIMD, tồn tại 3 loại vấn đề cơ bản hay còn được
gọi là cách lựa chọn thiết kế hiện vẫn là chủ đề đang được tranh cãi trong cộng
đồng các nhà nghiên cứu.
1. MPP – massively or moderately parallel processor. Việc xây
dựng một bộ xử lý song song từ một số lượng nhỏ các bộ xử lý
Trang 24
mạnh mẽ hay từ một số lượng rất lớn các bộ xử lý bình thường (một
“bầy voi” hay là một “đàn kiến”) thì cách nào sẽ hiệu quả hơn ?.
Theo luật của Amdahl thì cách đầu tiên thích hợp hơn cho những
phần tuần tự của một tính toán, trong khi cách tiếp cận thứ hai sẽ làm
tăng tốc hơn nữa những phần mang tính song song. Không thể đưa ra
một câu trả lời chung cho câu hỏi này, sự lựa chọn tốt nhất tùy thuộc
vào loại công nghệ và ứng dụng đang được sử dụng.
2. MIMD “chặt chẽ” hay “lỏng lẻo”. Cách tiếp cận nào tốt hơn cho
việc tính toán hiệu năng cao, bằng cách sử dụng đa bộ xử lý được
thiết kế đặc biệt trên nhiều máy tính hay là tập hợp của những máy
trạm bình thường được kết nối với nhau bởi các hệ thống mạng “tiện
nghi” (như là Ethernet hay ATM) và những tương tác nào sẽ được
kết nối với nhau bằng hệ thống phần mềm đặc biệt và các hệ thống
tập tin phân tán? Cách tiếp cận thứ hai đôi khi được biết đến là mạng
của các máy trạm (network of workstations hay là NOW) hay là tính
toán cluster, đã được sử dụng rộng rãi trong những năm gần đây. Tuy
nhiên vẫn còn nhiều vấn đề mở còn tồn tại nhằm phát huy tối đa khả
năng của những kiến trúc có nền tảng là mạng. Thiết bị phần cứng,
hệ thống phần mềm, và những khía cạnh ứng dụng của NOW đang
được đầu tư tìm hiểu bởi một số lượng lớn các nhóm ngiên cứu. Một
cách tiếp cận trung gian là kết hợp các cluster những bộ xử lý thông
qua môi trường mạng. Điều này về cơ bản là một phương pháp phân
nhánh, đặc biệt thích hợp khi có một sự truy cập rất lớn đến dữ liệu
cục bộ.
3. Truyền thông điệp tường minh hay chia sẽ bộ nhớ ảo. Lọai nào
sẽ tốt hơn, cho phép người dùng chỉ ra tất cả các loại thông điệp sẽ
được truyền giữa các bộ xử lý hay là cho phép họ lập trình ở một cấp
độ trừu tượng cao hơn, cùng với các thông điệp cần thiết tự động
được phát sinh bởi hệ thống phần mềm? Câu hỏi này về cơ bản là
tương tự với câu được hỏi trong những ngày đầu của những ngôn
Trang 25
ngữ lập trình cấp cao và bộ nhớ ảo. Tại một vài thời điểm trong quá
khứ, việc lập trình bằng hợp ngữ và thực hiện trao đổi giữa bộ nhớ
chính và bộ nhớ phụ có thể đem lại hiệu quả cao hơn. Tuy nhiên, do
ngày nay các phầm mềm đã đạt đến mức quá phức tạp, các trình biên
dịch cùng với hệ điều hành cũng đã quá cấp cao đến nỗi việc tối ưu
các chương trình bằng tay không còn là điều gì quá khó. Tuy nhiên
chúng ta vẫn chưa ở thời điểm xử lý song song đáng kể, và việc che
giấu cấu trúc giao tiếp tường minh giữa các máy tính song song ra
khỏi người lập trình sẽ đem lại hiệu năng thực thi rất đáng kể.
2.2.2. Tổ chức vật lý của các nền tảng song song và phân bố Trong phần này chúng ta sẽ chỉ mô tả một máy tính song song lý tưởng
là PRAM. Đây là một cách mở rộng tự nhiên của mô hình tính toán tuần tự
(Random Access Machine hay là RAM) bao gồm p bộ xử lý và một vùng nhớ
toàn cục có kích thước không giới hạn và được truy cập từ tất cá các bộ xử lý.
Tất cả chúng đều có sử dụng cùng chung một không gian địa chỉ. Các bộ xử lý
có thể cùng chia sẽ một đồng hồ chung nhưng cũng có thể thực thi các chỉ thị
khác nhau trên cùng một chu kỳ. Mô hình này được biết đến là parallel random
access machine (PRAM). Tùy thuộc vào cách thức truy cập bộ nhớ, PRAM
được phân thành 4 loại sau.
1. Toàn quyền đọc - Toàn quyền ghi (exclusive-read, exclusive write)
EREW. Trong loại này, truy cập vào vùng nhớ là toàn quyền. Không
có thao tác đọc ghi nào được cho phép. Đây là mô hình PRAM
không chắc chắn nhất, chỉ hỗ trợ truy cập đồng thời vào bộ nhớ một
cách tối thiểu.
2. Đồng thời đọc – Toàn quyền ghi (concurrent read, exclusive write)
CREW. Cho phép nhiều thao tác đọc cùng lúc trên cùng một vùng
nhớ, tuy nhiên nhiều thao tác ghi chỉ thực hiện theo tuần tự.
3. Toàn quyền đọc – Đồng thời ghi (exclusive read, concurrent write)
ERCW. Cho phép nhiều thao tác ghi cùng lúc trên cùng một vùng
nhớ, tuy nhiên nhiều thao tác đọc chỉ thực hiện theo tuần tự.
Trang 26
4. Đồng thời đọc – Đồng thời ghi (concurrent read, concurrent
write) CRCW. Trong loại này, cho phép nhiều thao tác đọc ghi
đồng thời trên cùng vùng nhớ chung. Đây là mô hình PRAM có
nhiều ưu điểm nhất.
Việc có nhiều thao tác đọc cùng một lúc không làm ảnh hưởng đến tính
nhất quán của chương trình. Tuy nhiên khi có nhiều thao tác ghi đồng thời
thì lại có ảnh hưởng lớn, vì thế có nhiều cách thức được đặt ra để giải quyết
vấn đề đó:
• Chung (common), thao tác ghi cùng lúc chỉ được thực hiện nếu tất cả
các bộ xử lý đều muốn ghi một giá trị như nhau.
• Tùy ý (arbitrary), chỉ cho phép một bộ xử lý bất kỳ được ghi.
• Ưu tiên (priority), tất cả các bộ xử lý được tổ chức theo một danh
sách ưu tiên được xác định trước, và bộ xử lý có quyền cao nhất sẽ
có quyền ghi.
• Tổng hợp (sum), trong đó giá trị tổng của các giá trị cần ghi sẽ được
ghi.
2.3. Một số mô hình lập trình song song thông dụng 2.3.1. Mô hình chia sẽ không gian bộ nhớ Lập trình song song tường minh thường yêu cầu chỉ ra cụ thể các tác vụ
song song cùng với các tương tác giữa chúng. Những tương tác này có thể ở
trong dạng đồng bộ giữa các tiến trình đồng thời hay là sự giao tiếp giữa các
kết quả trung gian. Trong kiến trúc chia sẽ không gian bộ nhớ, giao tiếp giữa
các tiến trình được chỉ ra là ngụ ý vì tất cả các bộ xử lý đều có quyền truy cập
vào một vài (hay tất cả) các bộ nhớ. Do đó, mô hình lập trình cho các máy tính
chia sẽ không gian địa chỉ tập trung chủ yếu vào các cách thức để thực thi đồng
thời, đồng bộ hóa và những cách để làm giảm sự quá tải do tương tác.
Các mô hình lập trình chia sẽ không gian địa có thể khác nhau về cách
thức chia sẽ dữ liệu, mô hình đồng thời, và hỗ trợ đồng bộ hóa. Các mô hình
giả sử rằng tất cả các dữ liệu của tiến trình đều mặc định là không được truy
cập, trừ khi nó cho phép làm điều đó (sử dụng các hàm gọi của hệ thống UNIX
Trang 27
như shmat và shmget). Mặc dù đây là một yếu tố quan trọng nhằm bảo mật
trong các hệ thống đa người dùng, tuy nhiên khí chúng cùng nhau hợp tác để
giải quyết cùng một vấn đề thì điều này là không còn cần thiết. Các chi phí do
bảo vệ dữ liệu gia tăng chỉ làm cho các tiến trình ít thích hợp hơn cho lập trình
song song. Ngược lại, các tiến trình và tiểu trình giả sử toàn bộ bộ nhớ là toàn
cục, và chúng sẽ thực hiện trao đổi thông tin với nhau một cách tường minh
thông qua đọc và ghi lên biến chia sẽ.
Hình 2-6 : Mô hình chía sẽ không gian bộ nhớ
Vì các tiến trình đều có quyền đọc và ghi lên vùng nhớ chung vào cùng
một thời điểm nên ta cần phải có một cơ chế đồng bộ hóa để bảo đảm tính đúng
đắn khi thao tác trên dữ liệu.
2.3.2. Mô hình truyền thông điệp Có rất nhiều ngôn ngữ lập trình và các thư viện được xây dựng nên để
dành cho lập trình song song. Những điều này khác nhau ở cách nhìn của
chúng về không gian địa chỉ dành cho người lập trình, mức đồng bộ trong các
chỉ thị song song và sự đa dạng của các chương trình. Mô hình lập trình truyền
thông điệp là một trong các mô hình cổ nhất và được sử dụng rộng rãi nhất
trong các mô hình dùng cho lập trình trên các máy tính song song. Lý do chính
cho việc này là vì nó yêu cầu tối thiểu về phần cứng bên dưới.
Trong phần này chúng ta sẽ đề cập một vài khái niệm căn bản về mô
hình truyền thông điệp và các kỹ thuật dùng với thư viện MPI (sẽ mô tả kỹ
trong chương sau).
Trang 28
Hình 2-7 : Mô hình truyền thông điệp
Có 2 tính chất quan trọng tạo nên bản chất của mô hình truyền thông
điệp là: thứ nhất là nó giả sử không gian địa chỉ được phân chia và thứ hai là nó
chỉ hỗ trợ song song hóa tường minh.
Cấu trúc của những chương trình truyền thông điệp
Các chương trình truyền thông điệp thường được viết bằng cách sử dụng
mô hình bất đồng bộ hay ít đồng bộ. Trong mô hình bất đồng bộ, tất cả các tác
vụ song song được thực thi một cách bất đồng bộ. Điều này cho phép ta có thể
triển khai bất cứ thuật toán song song nào. Tuy nhiên những chương trình như
vậy thường gặp khó khăn hơn để suy ra và bên cạnh đó cách thể hiện của nó
cũng khó mà đoán trước do những điều kiện về thực thi. Ngược lại những
chương trình ít đồng bộ có thể kết hợp tốt cả hai thái cực này. Trong những
chương trình như vậy, các tác vụ và những tập hợp con các tác vụ được đồng
bộ hóa để thực hiện những tương tác. Tuy nhiên giữa những tương tác này, các
tác vụ được thực thi hoàn toàn bất đồng bộ. Bởi vì những tương tác xảy ra một
cách đồng bộ, nên việc suy ra chương trình như vậy cũng khá dễ dàng. Nhiều
thuật toán song song phổ biến cũng được thực hiện một cách tự nhiên bằng
cách sử dụng những chương trình ít đồng bộ hơn.
Trong dạng phổ biến nhất của mình, mô hình truyền thông điệp hỗ trợ
thực thi cho các chương trình khác nhau trên từng bộ xử lý. Điều này cung cấp
tính mềm dẻo tối đa trong lập trình song song, nhưng điều này cũng làm cho
công việc viết các chương trình song song không thể mở rộng một cách hiệu
quả. Vì nguyên nhân này mà hầu hết các chương trình truyền thông điệp được
Trang 29
viết bằng cách sử dụng phương pháp single program multiple data (SPMD).
Trong những chương trình SPMD, các tiến trình khác nhau thực thi đoạn code
tương tự nhau ngọai trừ một số nhỏ các tiến trình (là những tiến trình “gốc”).
Điều này không có nghĩa là những tiến trình làm việc theo lock-step. Các
chương trình SPMD có thể là ít đồng bộ hay là hoàn toàn bất đồng bộ.
2.4. Cách thức xây dựng một chương trình song song và phân bố
Phát triển thuật toán là một phần quan trọng trong việc giải quyết vấn đề
khi sử dụng máy tính. Một thuật toán tuần tự về cơ bản là một phương pháp
thực hiện hay là một chuỗi tuần tự những bước cơ bản để giải quyết một vấn đề
được đặt ra bằng cách sử dụng máy tính tuần tự. Tương tự, một thuật tóan song
song là một phương pháp giải quyết vấn đề dựa trên việc sử dụng nhiều bộ xử
lý. Tuy nhiên, để chỉ ra được một thuật tóan song song không đơn giản như là
chỉ ra từng bước cụ thể. Mà là ở một mức độ nào đó, một thuật tóan song song
phải được thêm vào tính đồng thời và người thiết kế ra thuật toán cũng phải chỉ
ra tập hơp những bước có thể xử lý đồng thời. Điều này nhằm tận dụng được
khả năng tính toán của các máy tính song song. Trong thực tế việc thiết kế ra
một thuật tóan song song là khá phức tạp, nó có thể bao gồm một vài hay tất cả
những điều sau:
• Chỉ ra những phần của công việc có thể được thực thi đồng thời.
• Ánh xạ các phần của công việc vào nhiều bộ xử lý chạy song song.
• Phân tán dữ liệu nhập, xuất và trung gian cùng với chương trình.
• Quản lý truy cập vào dữ liệu chung giữa các bộ xử lý.
• Đồng bộ hóa các bộ xử lý khi thực thi các chương trình song song
2.4.1. Các thuật ngữ căn bản Phân họach : là quá trình phân chia một vấn đề cần tính toán thành
các phần nhỏ hơn, một vài hay tất cả các phần đó có thể xử lý song
song.
Tác vụ : là đơn vị do người lập trình định nghĩa để chỉ ra các phần
tính toán sau khi phân họach. Xử lý đồng thời nhiều tác vụ là điều
Trang 30
kiện tiên quyết để rút ngắn thời gian giải quyết toàn bộ vấn đề. Các
tác vụ có thể không cùng kích thước. Đồ thị phụ thuộc : là một thể hiện sự phụ thuộc giữa các tác vụ và
trật tự thực hiện giữa chúng. Một đồ thị phụ thuộc là một đồ thị có
hướng trong đó mỗi nút của cây là một tác vụ và cạnh có hướng thể
hiện sự phụ thuộc giữa chúng. Một tác vụ chỉ được thực hiện khi các
tác vụ trước nó (có cạnh nối) được thực hiện. Trong đồ thị phụ thuộc
tập hợp cạnh có thể rỗng.
Hình 2-8 : Đồ thị phụ thuộc tác vụ
Granularity : số lượng và kích thước của các tác vụ sau bước phân
họach được gọi là granularity của bước phân họach. Bước phân
họach một vấn đề lớn thành một số lượng lớn các vấn đề nhỏ được
gọi là fine-grained và thành một số lượng nhỏ các vấn đề lớn đựơc
gọi là coarse-grained.
Đồ thị tương tác : là mô hình thể hiện sự tương tác giữa các tác vụ.
Các nút trong đồ thị tương tác thế hiện các tác vụ còn các cạnh nối
thể hiện tưong tác giữa chúng. Các cung trong đồ thị tương tác
thường là cung vô hướng. Tập hợp cạnh thuờng là tập hợp cha của
tập hợp cạnh của đồ thị phụ thuộc
Trang 31
Hình 2-9 :Đồ thi tương tác trong bài toán nhân ma trận với vector
2.4.2. Thiết kế thuật toán song song Phân chia một công việc tính toán thành các phần nhỏ hơn và ánh xạ
chúng vào các bộ xử lý khác nhau để thực hiện song song là 2 bước cơ bản
trong vịêc thiết kế một thuật tóan song song.
2.4.2.1. Một số phương pháp phân hoạch Một trong những bước cơ bản mà chúng ta cần làm để giải quyết một
vấn đề theo hướng song song là phân chia những phép tính toán muốn thực
hiện thành môt tập hợp các tác vụ nhỏ hơn để xử lý đồng thời như trong đồ thị
phụ thuộc tác vụ. Trong phần này chúng ta sẽ mô tả một vài kỹ thuật phân
họach phổ biến cho xử lý đồng hành. Các kỹ thuật này không phải là tất cả các
kỹ thuật phân họach có thể có. Thêm vào đó, những phương pháp phân họach ở
đây không bảo đảm sẽ dẫn tới những thuật toán song song tốt nhất cho một vấn
đề nào đó. Mặc dù còn một vài thiếu sót, nhưng các kỹ thuật phân họach được
đề cập trong phần này là điểm bắt đầu tốt cho nhiều vấn đề và một hay nhiều sự
kết hơp của các kỹ thuật này có thể được dùng để đạt được các phân họach hiệu
quả cho rất nhiều lọai vấn đề.
Các kỹ thuật phân họach phân họach ở đây có thể phân thành các lọai
sau phân họach đệ quy, phân họach dữ liệu, phân họach thăm dò và phân
họach suy đóan. Trong đó phân họach đệ quy và phân họach dữ liệu được
dùng cho nhiều lọai vấn đề còn các phương pháp phân họach khác chỉ được sử
dụng cho một lọai vấn đề cụ thể nào đó.
Phân họach đệ quy
Trang 32
Phân họach đệ quy là một phương pháp dùng để tạo ra sự đồng hành
trong những vấn đề có thể được giải quyết bằng phương pháp chia-và-trị.
Trong kỹ thuật này trước tiên một vấn đề được giải quyết bằng cách phân chia
nó thành tập hợp các vấn đề con độc lập với nhau. Đến phiên các vấn đề con lại
tiếp tục áp dụng cách thức phân họach đệ quy thành các vấn đề con khác nhỏ
hơn. Cuối cùng là chúng ta sẽ thực thi đồng hành các vấn đề con độc lập này,
kết quả của vấn đề lớn là sự kết hợp kết quả của các vấn đề con nhỏ hơn.
Phân hoạch dữ liệu
Phân họach theo dữ liệu là một phương pháp phân hoạch hiệu quả và
được sử dụng nhiều nhất trong việc xác định tính đồng hành trong các thuật
toán để có thể thao tác trên các cấu trúc dữ liệu lớn. Phương pháp này bao gồm
2 bước. Trong bước 1, dữ liệu trong bước tính tóan sẽ được phân ra thành từng
phần, và trong bước 2, phần dữ liệu này sẽ được chuyển thành các tác vụ.
Những thao tác mà các tác vụ thực hiện trên các phần dữ liệu khác nhau thường
là tương tự nhau hay được chọn từ tập hợp các thao tác nhỏ hơn.
Chúng ta sẽ xem xét cụ thể các cách phân chia dữ liệu có thể ở phần bên
dưới. Nhìn chung, thì người thiết kế phải tự tìm ra và đánh giá các cách phân
chia dữ liệu để quyết định xem cách nào phân họach “tự nhiên” và hiệu quả
nhất.
Phân chia dữ liệu xuất
Trong nhiều phần tính toán, từng phần xuất có thể được xử lý độc lập
với các phần khác. Trong nhiều phần tính toán như vậy, việc phân chia dữ liệu
xuất tự động dẫn đến việc phân họach những vấn đề thành các tác vụ, với mỗi
tác vụ được kết gán cho công việc tính toán một phần của kết quả xuất.
vd: nhân ma trận
Hãy xem vấn đề nhân 2 ma trận nxn A và B, kết quả trả về là ma trận C.
Trước tiên ta phân từng ma trận thành 4 khối hay ma trận con, bằng cách chia
các chiều của ma trận theo 1 nửa. 4 ma trận con của ma trận kết quả C, mỗi
phần có kích thước n/2 x n/2, có thể được tính tóan độc lập với nhau bởi 4 tác
vụ.
Trang 33
Hình 2-10 : (a) Phân các ma trận nhập và xuất thành các ma trận con
(b) Phân hoạch phép nhân ma trận thành 4 tác vụ
Hầu hết các thuật toán ma trận, bao gồm nhận ma trận với vector và
nhân ma trận với ma trận, có thể được công thức hóa thành các thao tác trên
khối ma trận. Trong các công thức này, từng ma trận được xem như bao gồm
các khối hay các ma trận con, các phép tính toán được thực hiện trên từng phần
tử và được thay thế tương ứng bởi các phép tóan trên các khối ma trận con. Kết
quả có được trên từng phần tử hay trên các khối là tương tự nhau. Thuật toán
ma trận khối thường được dùng để hỗ trợ cho việc phân họach.
Chúng ta phải chú ý là phân họach theo dữ liệu khác với phân họach các
phép tính thành các tác vụ. Mặc dù 2 khái niệm này thường có liên hệ với nhau,
và cái đầu thường hỗ trợ cho cái sau, một kết quả phân họach dữ liệu đã cho
không chỉ có một cách để phân chúng thành các tác vụ.
Phân chia dữ liệu nhập
Phân chia theo dữ liệu xuất chỉ có thể được thực hiện nếu từng kết quả
xuất có thể được tính toán một cách tự nhiên theo chức năng nhập. Trong nhiều
thuật toán, việc phân chia theo dữ liệu xuất là điều không thể. Ví dụ như khi
tìm giá trị lớn nhất, nhỏ nhất hay tổng của các số đã cho, kết quả xuất là điều
không thể biết trước. Trong các thuật toán sắp xếp, từng phần tử riêng biệt của
kết quả không thế được xác định một cách hiệu quả. Trong những trường hợp
Trang 34
như vậy, việc phân chia theo dữ liệu nhập là hoàn toàn có thể, và sau đó dùng
kết quả này để thực hiện đồng thời việc tính toán. Từng tác vụ được tạo ra cho
từng phần dữ liệu nhập và tác vụ này sẽ sử dụng tối đa các phép tính có thể
thực hiện trên các dữ liệu cục bộ này. Lưu ý là những giải pháp cho các tác vụ
được đúc kết từ dữ liệu nhập có thể không giải quyết được một cách trực tiếp
vấn đề gốc. Trong những trường hợp như vậy, thì kết quả tính toán có thể được
thực hiện bằng cách “nổi bọt” lên phía trên.Ví dụ như khi tìm tổng của một
chuỗi gồm N số dùng p tiến trình (p < N), chúng ta có thể phân chia phần dữ
liệu nhập thành p phần con (có kích thước gần bằng nhau). Từng tác vụ thực
hiện cộng các số trong từng phần con. Kết quả cuối cùng là cộng của p phần
con vừa được tính.
Phân chia cả dữ liệu xuất và nhập
Trong nhiều trường hợp việc phân chia theo cả kết quả xuất và dữ liệu
nhập có thể làm tăng khả năng xử lý đồng thời.
Phân chia dữ liệu trung gian
Các thuật toán thường có dạng xử lý gồm nhiều giai đọan khác nhau,
trong đó kết quả xuất của giai đọan này là kết quả nhập của giai đọan theo sau
nó. Quá trình phân họach cho những thuật toán như vậy có thể được thực hiện
bằng cách phân chia theo dữ liệu nhập hay theo dữ liệu xuất của một giai đọan
trung gian. Phân chia theo dữ liệu trung gian đôi khi dẫn tới khả năng xử lý
đồng thời cao hơn so với khi thực hiện trên dữ liệu nhập hay xuất. Thông
thường trong giải quyết một vấn đề nào đó thì dữ liệu trung gian không được
phát sinh một cách tường minh và trong khi cấu trúc lại các thuật tóan ban đầu
người ta có thể cần đến dữ liệu trung gian để tạo ra sự phân họach.
vd: như trong ví dụ nhân ma trận bên trên, ta có thể gia tăng khả năng
tính tóan song song bằng cách đưa ra một bước trung gian mà trong đó có 8 tác
vụ thực hiện tính toán các ma trận con tương ứng của chúng rồi lưu kết quả
trong một ma trận 3 chiều D. Ma trận con Dk,i,j là kết quả của việc nhân Ai,k và
Bk,j.
Trang 35
Hình 2-11 : Nhân hai ma trận A và B với phần trung gian là ma trận D
Việc phân chia thành ma trận trung gian D dẫn đến phân hoạch thành 8
tác vụ. Sau bước nhân, ta thực hiện cộng các ma trận kết quả con (chi phí
không cao) thành ma trận C. Tất cả các ma trận con D*,i,j được cộng lại với
nhau để tạo thành Ci,j. 8 tác vụ (đánh số từ 1-8) thực hiện việc nhân các ma trận
con của A và B có kích thước n/2 x n/2 với chi phí là O(n3/8). Sau đó 4 tác vụ
(đánh số từ 9-12) thực hiện cộng các ma trận con trung gian D thành ma trận
kết quả C với chi phí là (n2/8).
Trang 36
Hình 2-12 : Phân họach bài toán nhân ma trận theo ma trận trung gian
3-chiều
Phân hoạch thăm dò
Phân họach thăm dò được dùng để phân họach những vấn đề mà có nội
dung tính toán tương ứng với một không gian tìm kiếm của những giải pháp.
Trong phân họach thăm dò, chúng ta phân chia không gian tìm kiếm thành
nhiều phần nhỏ hơn, và thực hiện tìm kiếm trên từng phần đồng thời với nhau,
cho đến khi tìm ra giải pháp cần tìm.
Trang 37
Lưu ý là mặc dù phân hoạch thăm dò trông có vẻ tương tự như phân
hoạch dữ liệu (không gian tìm kiếm có thể được xem như là dữ liệu được phân
chia), về cơ bản chúng khác nhau ở những điểm sau đây. Những tác vụ có được
sau khi phân hoạch dữ liệu được thực hiện hoàn toàn và từng tác vụ đều thực
hiện các phép tính hữu dụng để tìm ra giải pháp cho vấn đề. Mặt khác, trong
phân hoạch thăm dò, những tác vụ mặc dù chưa thực hiện xong nhưng vẫn bị
kết thúc nếu đã có một giải pháp được tìm ra từ một tác vụ khác. Vì thế từng
phần của không gian tìm kiếm khi được thực hiện bởi công thức song song có
thể khác rất nhiều so với khi được tìm kiếm bởi thuật toán tuần tự. Cho nên số
lượng công việc mà công thức song song thực hiện có thể nhiều hơn hay ít hơn
so với khi thực hiện bằng thuật toán tuần tự.
Trang 38
Hình 2-13 : Các bước phát sinh theo phân hoạch thăm dò
Phân hoạch suy đoán
Trang 39
Phân hoạch suy đoán được dùng khi một chương trình có thể lấy một
trong các nhánh tính toán có thể, tùy thuộc vào kết quả xuất của những phép
tính toán trước đó. Trong trường hợp này, trong khi một tác vụ đang thực hiện
các phép tính mà kết quả xuất sẽ quyết định bước tính toán tiếp theo, trong khi
các tác vụ khác có thể bắt đầu đồng thời các công việc tính toán của giai đoạn
tiếp theo. Ngữ cảnh này trông giống với ước lượng song song một hay nhiều
nhánh của câu lệnh switch trong ngôn ngữ C trước khi tồn tại giá trị vào của
câu lệnh. Trong khi một tác vụ thực hiện tính toán để giải quyết switch, các tác
vụ khác thực hiện song song trên các nhánh khác của switch. Khi giá trị đầu
vào cuối cùng của switch được tính ra, thì nhánh có các phép tính tương ứng sẽ
được thực hiện trong khi bỏ qua các nhánh còn lại. Thời gian cho việc chạy
song song sẽ nhỏ hơn khi chạy tuần tự vì thời gian được sử dụng tối ưu để thực
hiện song song các phép tính toán hợp lý cho giai đoạn tiếp theo. Tuy nhiên
dạng song song của switch cũng bảo đảm sẽ có ít nhất một vài phép tính toán
lãng phí. Nhằm làm giảm các phép tính toán này, một dạng khác nhỏ của phân
họach suy đoán có thể đuợc sử dụng, đặc biệt trong những trường hợp mà một
trong các kết quả xuất của switch có khả năng xảy ra hơn so với các trường hợp
còn lại. Trong trường hợp này, chỉ có nhánh ‘khả thi” nhất được một tác vụ
thực thi song song cùng với các phép tính toán trước đó. Nhưng nếu kết quả
xuất của switch khác với những gì được mong đợi thì ta sẽ “roll back” lại việc
tính toán và thực thi chính xác nhánh switch cần thực hiện.
Phân hoạch suy đoán và phân hoạch thăm dò khác nhau ở một vài điểm
sau. Trong phân hoạch suy đoán đầu vào là không biết, còn trong phân hoạch
thăm dò kết quả đầu ra là không biết. Trong phân hoạch suy đoán, thuật toán
tuần tự sẽ chỉ thực hiện nghiêm ngặt một trong các tác vụ ở giai đọan suy đoán,
bởi vì khi mà nó bắt đầu thực hiện một giai đoạn nào đó, nó đã biết chính xác
phải thực hiện theo nhánh nào. Một chương trình song song khi thực hiện theo
phân hoạch suy đoán sẽ phải làm nhiều công việc hơn so với chương trình đó
khi viết theo tuần tự. Mặt khác trong phân hoạch thăm dò, thuật toán tuần tự
tìm ra nhiều hướng đi, do mỗi nhánh đều dẫn tới một giải pháp mà chưa được
biết trước. Vì thế, một chương trình song song có thể thực hiện ít hơn, nhiều
Trang 40
hơn hay bằng với số lượng công việc của thuật toán tuần tự tùy thuộc vào vị trí
của giải pháp trong không gian tìm kiếm.
Kết hợp các phép phân hoạch
Cho đến bây giờ chúng ta đã xem xét một số phương pháp phân hoạch
có thể được dùng để tạo ra một số mô hình song song cho các thuật toán.
Những kỹ thuật này không phải là hoàn toàn tuyệt đối mà nguợc lại chúng có
thể được sử dụng kết hợp với nhau. Thông thường một phép tính được phân
thành nhiều bước và đội khi ta phải áp dụng nhiều cách phân hoạch cho các
buớc khác nhau. Ví dụ như khi tìm giá trị nhỏ nhất của một tập hợp số n rất
lớn, phương pháp phân hoạch đệ quy thuần túy có thể làm phát sinh ra nhiều
tác vụ hơn là số bộ xử lý đang có. Một cách phân hoạch hiệu quả là chia dữ liệu
ban đầu thành P phần bằng nhau và gán vào cho P bộ xử lý. Kết quả cuối cùng
có được bằng cách tìm giá trị nhỏ nhất của các kết quả trung gian bằng cách áp
dụng phân hoạch đệ quy.
Hình 2-14 : Phân hoạch lai để tìm giá trị nhỏ nhất của mảng
2.4.2.2. Ánh xạ Một khi bài toán đã được phân rã thành các tác vụ, thì các tác vụ này sẽ
được ánh xạ vào trong các tiến trình xử lý với mục tiêu là hoàn thành tất cả
trong thời gian ngắn nhất. Để đạt được thời gian xử lý nhỏ thì chi phí cho thực
thi song song các tác vụ phải được giảm đến mức tối thiểu. Với một phân
họach đã cho thì có hai yếu tố chính dẫn đến chi phí là : thời gian cho giao tiếp
giữa các tiến trình và thời gian khi chúng nhàn rỗi. Một tiến trình có thể nhàn
rỗi vì nhiều lý do trước khi toàn bộ các phép tính được hoàn tất. Sự phân bố
không đều có thể làm cho một vài tiến trình hoàn thành công việc trước những
tiến trình khác. Hoặc cũng có thể do các tác vụ chưa thực hiện được ánh xạ vào
Trang 41
các tiến trình đang bận thực hiện một tác vụ khác gây ra thời gian chờ. Vì thế
một cách ánh xạ các tác vụ được đánh giá là tốt khi nó đạt được hai mục tiêu
sau :
• Giảm thiểu thời gian các tiến trình trao đổi với nhau.
• Giảm thiểu tổng thời gian khi các tiến trình này nhàn rỗi trong khi
các tiến trình khác phải thực thi nhiều tác vụ.
Hai mục tiêu đó thường mâu thuẫn với nhau. Ví dụ, khi bạn muốn giảm
đến mức tối thiểu tương tác giữa các tiến trình bằng cách kết gán một tập hợp
các tác vụ vào cùng một tiến trình. Trong nhiều trường hợp như vậy, phép kết
gán như vậy sẽ đem lại sự mất cân bằng tải giữa các tiến trình, gây ra thời gian
nhàn rỗi cho các tiến trình khác.
Trong phần này chúng ta sẽ xem xét nhiều cách thức để ánh xạ các tác
vụ vào trong các tiến trình với mục tiêu chính là cân bằng tải và giới hạn đến
nhỏ nhất thời gian tương tác giữa chúng.
vd: trong ví dụ sau cho ta thấy cách ánh xạ 12 tác vụ vào trong 4 tiến
trình, mà trong đó 4 tác vụ cuối cùng chỉ có thể được thực hiện khi 8 tác vụ
trước đó đã được hoàn tất. Trong hình bên dưới thể hiện hai cách ánh xạ khác
nhau, mỗi các sẽ đem lại thời gian hoàn tất khác nhau
Hình 2-15 : Hai cách phân hoạch với đồng bộ hóa
Các kỹ thuật ánh xạ đại khái có thể phân thành hai loại chính là ánh xạ
tĩnh và ánh xạ động. Mô hình lập trình song song, tính chất của các tác vụ và sự
tương tác giữa chúng sẽ quyết định nên chọn cách ánh xạ nào cho thích hợp.
Trang 42
• Ánh xạ tĩnh (static): kỹ thuật ánh xạ tĩnh phân phối tác vụ giữa các
tiến trình tùy thuộc tính ưu tiên trong việc thực thi các thuật toán.
Đối với những tác vụ được phát sinh tĩnh thì áp dụng một trong hai
kỹ thuật đều khả thi. Việc chọn ra được một cách ánh xạ tốt thì còn
phụ thuộc vào nhiều yếu tố, bao gồm kích thước của tác vụ, kích
thước của dữ liệu đi kèm với chúng, tính chất tương tác giữa các tác
vụ, và thậm chí là mô hình lập trình song song được sử dụng. Tuy
nhiên trong nhiều trường hợp thực tế phương pháp heuristic cũng
đem lại giải pháp gần đúng chấp nhận được cho việc tối ưu vấn đề
ánh xạ tĩnh.
Các thuật toán mà sử dụng ánh xạ tĩnh thì nhìn chung dễ dàng
hơn cho việc hiết kế và lập trình.
• Ánh xạ động (dynamic): kỹ thuật ánh xạ động phân phối công việc
giữa các tiến trình trong suốt quá trình thực thi thuật toán. Nếu các
tác vụ được phát sinh động thì nó cũng sẽ được ánh xạ động. Nếu
kích thước của tác vụ là chưa biết thì nếu sử dụng ánh xạ tĩnh sẽ dẫn
đến sự mất cân bằng tải nghiêm trọng và trong trường này sử dụng
ánh xạ động sẽ hiệu quả hơn. Nếu số lượng dữ liệu đi kèm các tác vụ
là khá lớn cho việc tính toán thì khi dùng phương pháp này sẽ đưa
đến việc chia sẽ dữ liệu giữa các tiến trình. Chi phí cho việc di
chuyển này có thể ảnh hưởng hơn so với những ưu điểm của ánh xạ
động và dẫn đến việc sử dụng ánh xạ tĩnh sẽ hiệu quả hơn. Tuy
nhiên, trong mô hình chia sẽ không gian địa chỉ thì phương pháp này
cũng hữu hiệu hơn thậm chí đối với các dữ liệu lớn.
Các thuật toán đòi hỏi ánh xạ động thì thường là phức tạp hơn, đặc biệt
là trong mô hình truyền thông điệp.
Vd cách ánh xạ trong bài toán nhân ma trận
Trang 43
Hình 2-16 : phân chia theo (a) 1 chiều và (b) hai chiều của ma trận
xuất. Những phần màu xám là dữ liệu mà tiến trình cần để tính toán.
2.4.3. Một số phương pháp tối ưu Như đã lưu ý ở trên, làm giảm tương tác quá mức giữa các tiến
trình là một điều quan trọng cho một chương trình song song hiệu quả.
Nguyên nhân xảy ra điều này có thể do nhiều yếu tố, như kích thước của dữ
liệu dùng trong quá trình tương tác, tần số tương tác…
Trong phần này chúng ta sẽ xem xét một vài phương pháp tổng
quát để làm hạn chế quá tải do tương tác xảy ra trong các chương trình song
song. Tất cả các kỹ thuật này có thể không thích hợp cho mô hình lập trình
song song và một vài trong số đó cần sự hỗ trợ của phần cứng bên dưới.
2.4.3.1. Tối đa hóa dữ liệu cục bộ
Trong hầu hết các chương trình song song, các tác vụ được thực
thi bởi các tiến trình khác nhau đòi hỏi phải được truy cập đến dữ liệu
chung. Ví dụ như trong bài toán nhân ma trận và vector y=Ab , trong đó
Trang 44
từng tác vụ thực hiện tính toán từng phần tử của vector y và cần phải truy
cập đến các phần tử của vector nhập b. Các kỹ thuật nhằm gia tăng sử dụng
dữ liệu cục bộ bao gồm một pham vi rộng lớn các cách thức nhằm giảm
thiểu tối đa kích thước của các dữ liệu truyền tải, tối đa hóa việc sử dụng lại
các dữ liệu vừa được truy cập, và cực tiểu số lần truy cập.
• Cực tiểu dữ liệu trao đổi
Một phương pháp cơ bản nhằm làm giảm sự tương tác quá mức
là làm giảm đến mức tối đa dữ liệu chia sẽ cần để truy cập bởi nhiều tiến
trình cùng một lúc. Điều này tương tự với việc tối đa hóa sử dụng dữ liệu
cục bộ một cách tạm thời, nghĩa là thực hiện tham chiếu liên tục đến càng
nhiều dữ liệu càng tốt. Rõ ràng càng nhiều bước tính toán trên dữ liệu cục
bộ có sẵn sẽ góp phần xóa đi yêu cầu chuyển dữ liệu vào vùng đệm cho các
tiến trình xử lý. Như đã nói ở trên để đạt được điều này cần áp dụng các
phương pháp phân hoạch và ánh xạ thích hợp. Ví dụ như trong bài toán
nhân ma trận nếu ta áp dụng ánh xạ 2 chiều thì kích thước dữ liệu chia sẽ
cần được truy cập chỉ là pn22
, còn nếu áp dụng ánh xạ 1 chiều thì kích
thước sẽ lên tới 2
2
np
n+
. Nói tóm lại, phân bố với số chiều càng cao thì
càng làm giảm khối lượng của dữ liệu cần chia sẽ.
Một cách khác để làm giảm sự truy cập của các tiến trình đến dữ
liệu chia sẽ là sử dụng dữ liệu cục bộ để lưu kết quả trung gian, và chỉ thực
hiện truy cập đến dữ liệu chia sẽ tại nơi sẽ tính toán kết quả cuối cùng.
• Cực tiểu tần số tương tác
Đây là một phương pháp quan trọng trong việc làm giảm sự quá
tải tương tác trong các chương trình song song bởi vì trong nhiều kiến trúc
thì chi phí kích hoạt cho từng tương tác là khá lớn. Ta có thể làm giảm tần
số tương tác bằng cách tái cấu trúc lại các thuật toán sao cho các dữ liệu
chia sẽ được truy cập và sử dụng thành các phần lớn.
2.4.3.2. Giảm thiểu tối đa các điểm xung đột, tranh chấp
Trang 45
Phần bàn luận của chúng ta cho đến bây giờ chỉ là tập trung làm
giảm tương tác quá mức chủ yếu bằng cách trực tiếp hay gián tiếp làm giảm
tần số và dụng lượng dữ liệu trao đổi. Tuy nhiên mô hình tương tác giữa các
tác vụ thường dẫn đến tranh chấp làm gia tăng sự tương tác. Nói chung,
tranh chấp xảy ra khi nhiều tác vụ cùng truy cập đồng thời vào tài nguyên.
Nhiều luồng trao đổi dữ liệu trên cùng một đường liên kết, nhiều sự truy
cập cùng lúc vào cùng một khối nhớ, hay nhiều tiến trình thực hiện gửi
những thông điệp đến cùng một tiến trình vào cùng một thời điểm, tất cả có
thể dẫn đến sự xung đột. Điều này bởi vì chỉ một trong nhiều thao tác có thể
được thực thi tại một thời điểm còn những thao tác còn lại phải được sắp
xếp và thực hiện tuần tự.
Xem lại bài toán nhân hai ma trận C = AB, sử dung phương pháp
phân hoạch theo 2 chiều như hình bên trên (Hình 2.16). Gọi p là số lượng
các tác vụ được ánh xạ 1-1 vào trong các tiến trình. Mỗi tác vụ sẽ chịu trách
nhiệm tính toán một phần tử Ci,j của ma trận kết quả C, với pji <≤ ,0 .
Phần tử Ci,j được tính theo công thức (viết theo ký hiệu ma trận khối):
∑−
=
=1
0,,, *
p
kjkkiji BAC
Xem cách truy cập vào bộ nhớ của công thức trên, chúng ta thấy
rằng bất cứ tại bước p nào, thì p các tác vụ cũng sẽ truy cập vào cùng
một khối của ma trận A và B. Trong trường hợp đặc biệt, tất cả các tác vụ
làm việc trên cùng một dòng của C cũng sẽ truy cập lên cùng một khối của
A. Ví dụ như tất cả p tiến trình tính C0,0, C0,1, …, C0, 1−p cũng sẽ cùng
đọc A0,0 cùng một lúc. Tương tự như vậy tất cả các tác vụ làm việc trên
cùng một cột của C cũng sẽ truy cập lên cùng một khối của B. Nhu cầu truy
cập đồng thời lên cùng các khối nhớ này của ma trận A và B sẽ tạo ra xung
đột trên cả kiến trúc chia sẽ không gian bộ nhớ NUMA và kiến trúc truyền
thông điệp.
Trang 46
Một cách để làm giảm tranh chấp này là thiết kế lại thuật toán
song song để nó truy cập vào dữ liệu theo các mẩu không xung đột. Ví dụ
như thuật toán nhân ma trận, chúng ta có thể hiệu chỉnh thứ tự các khối ma
trận được nhân với nhau bằng cách sử dụng công thức:
∑−
=++++
=1
0,)%()%(,, *
p
kjpkjipkjiiji BAC
Bằng cách sử dụng công thức này tất cả các tác vụ P*,j làm việc
trên cùng một dòng của C sẽ truy cập vào khối nhớ A*, (*+j+k)% p , khác
nhau cho từng tác vụ. Vì vậy chỉ bằng cách sắp xếp lại thứ tự nhân các khối
với nhau, ta có thể loại bỏ tranh chấp. Ví dụ như trong các tiến trình tính
toán khối dòng của C, thì tiến trình tính toán C0,j sẽ truy cập A0,j từ khối
dòng đầu tiên của ma trận A thay vì A0,0.
Việc sử dụng ánh xạ động thường là nguồn gốc của những tranh
chấp trên cấu trúc dữ liệu chia sẽ hay là từ các kênh giao tiếp dẫn đến tiến
trình chính.
2.4.3.3. Đan xen các phép tính và tương tác
Thời gian mà các tiến trình chờ các dữ liệu chia sẽ đến hay nhận
thêm một công việc sau khi tương tác có thể được làm giảm xuống, thông
thường là theo từng phần, bằng cách thực hiện một số phép tính tiện ích
trong suốt thời gian chờ đợi.
Một cách đơn giản để đan xen là khởi gán tương tác đủ sớm để
nó hoàn tất trước khi cần cho tính toán. Đề đạt được điều này, chúng ta phải
có thể nhận ra các phép tính có thể trước khi thực hiện tương tác. Sau đó
trong chương trình song song phải được cấu trúc sao cho thực hiện khởi gán
tương tác trước thời điểm mà nó thực hiện trong thuật toán gốc. Về cơ bản,
điều này là có thể nếu có nhiều tác vụ sẵn sàng thực thi có sẵn trên cùng
một tiến trình sao cho nếu có một khối chờ cho việc tương tác hoàn tất thì
tiến trình vẫn có thể thực thi các tác vụ khác.
Trong nhiều trường hợp, đan xen các phép tính và sự tương tác
đòi hỏi phải có sự hỗ trợ từ mô hình lập trình , hệ điều hành, và thiết bị
Trang 47
phần cứng. Mô hình lập trình phải cung cấp một cách thức cho phép tương
tác và tính toán được tiến hành đồng thời. Cách thức này phải được hỗ trợ
bởi phần cứng bên dưới. Mô hình và kiến trúc không gian địa chỉ không
liên kết thường cung cấp sự hỗ trợ này thông qua truyền thông điệp ưu tiên
dạng non-blocking. Mô hình lập trình cung cấp các hàm cho việc gửi và
nhận thông điệp cho phép trả quyền điều khiển cho chương trình người
dùng trước khi nó thực sự hoàn tất. Vì thế chương trình có thể sử dụng các
hàm ưu tiên này để khởi tạo những tương tác và sau đó thực hiện các phép
tính toán. Nếu phần cứng cho phép tính toán được thực hiện song song với
trao đổi thông điệp, thì sự tương tác có thể giảm đáng kể.
2.4.3.4. Tạo bản sao dữ liệu hay các phép tính toán
Trong một vài thuật toán song song, nhiều tiến trình có thể đòi
hỏi truy cập chỉ đọc thường xuyên vào một cấu trúc dữ liệu chia sẽ, như là
bảng băm. Ví thế trừ khi không được phép yêu cầu thêm bộ nhớ, còn không
thì nên tạo một bản sao cấu trúc dữ liệu chia sẽ cho mỗi tiến trình để sau khi
khởi gán tương tác, tất cả các những truy cập tiếp theo vào cấu trúc dữ liệu
này sẽ không gây quá tải do tương tác.
Trong mô hình chia sẽ không gian bộ nhớ, việc tạo bản sao của
các dữ liệu chỉ đọc, được truy cập thường xuyên thì thường bị chịu tác động
bởi những cache mà không phải do sự can thiệp tường minh của lập trình
viên. Nhân bản dữ liệu một cách tường minh thường thích hợp cho các kiến
trúc và mô hình lập trình mà gặp phải những chi phí đáng kể khi truy cập
vào dữ liệu chia sẽ. Vì thế mô hình truyền thông điệp là được lợi nhất khi ta
thực hiện tạo bản sao dữ liệu ở các tiến trình, điều này có thể làm giảm đáng
kể sự quá tải do tương tác và cũng làm đơn giản hơn khi viết các chương
trình song song.
Tuy nhiên tạo bản sao dữ liệu không phải là không tốn chi phí.
Nó làm gia tăng bộ nhớ của chương trình song song. Dung lượng bộ nhớ
yêu cầu gia tăng lũy tiến cùng với số lượng tiến trình chạy đồng thời. Điều
này có thể làm giới hạn lại kích thước vấn đề có thể được giải quyết trên
Trang 48
một máy tính song song đã cho. Vì lý do này mà sao lưu dữ liệu phải được
sử dụng một cách lựa chọn cho số lượng dữ liệu tương đối nhỏ.
Bên cạnh dữ liệu nhập, các tiến trình trong một chương trình
song song cũng thường chia sẽ kết quả trung gian. Trong những trường hợp
như vậy, để cho các tiến trình tự tính toán kết quả trung gian sẽ hiệu quả
hơn so với lấy chúng từ những tiến trình khác.
2.4.4. Các mô hình thuật toán song song Sau khi tìm hiểu về các kỹ thuật phân hoạch, ánh xạ và giảm
thiểu tối đa tần số tương tác, bây giờ chúng ta sẽ giới thiệu một vài mô hình
thuật toán song song hay được sử dụng. Một mô hình thuật toán là một cách
thức tiêu biểu nhằm cấu trúc hóa lại một thuật toán song song bằng cách lựa
chọn ra một kỹ thuật phân hoạch và ánh xạ và áp dụng kế hoạch thích hợp
để tối ưu việc tương tác.
2.4.4.1. Mô hình dữ liệu song song
Đây là một trong những mô hình thuật toán đơn giản nhất, các tác
vụ được ánh xạ tĩnh hay bán tĩnh vào trong các tiến trình và từng tác vụ sẽ
thực hiện cùng một thao tác trên các dữ liệu khác nhau. Loại song song mà
có các chỉ thị tương tự nhau được áp dụng đồng thời lên các dữ liệu khác
loại nhau được gọi là loại song song dữ liệu (data parallelism). Công việc
có thể được thực hiện từng bước và dữ liệu thao tác trên các bước khác
nhau có thể khác nhau. Bởi vì tất cả các tác vụ đều cùng thực thi các chỉ thị
giống nhau, nên phương pháp phân hoạch được sử dụng ở đây là phân
hoạch theo dữ liệu do một phương pháp phân hoạch thống nhất theo sau là
cách thức ánh xạ tĩnh là đủ khả năng để đảm bảo cân bằng tải.
Những thuật toán song song về dữ liệu có thể được áp dụng cho
cả mô hình chia sẽ không gian bộ nhớ và truyền thông điệp.
Tương tác trong mô hình này có thể làm giảm thiểu tối đa bằng
cách áp dụng các cách thức phân họach riêng biệt cục bộ, và nếu có thể thì
bằng cách chồng lấp các phép tính và các tương tác hoặc cũng có thể bằng
cách sử dụng các thủ tục tối ưu các tương tác tập thể. Tính chất cốt lõi của
Trang 49
các vấn đề song song dữ liệu là trong hầu hết các vấn đề, mức độ song song
của dữ liệu sẽ gia tăng cùng với kích thước của vấn đề, điều này làm tăng
khả năng giải quyết các vấn đề lớn hơn bằng cách gia tăng số lượng bộ xử
lý được sử dụng.
2.4.4.2. Mô hình đồ thị tác vụ
Như đã nói ở trên, các phép tính toán trong bất kỳ thuật toán song
song nào cũng có thể được biểu diễn theo đồ thị phụ thuộc tác vụ. Nó có thể
đơn giản như trong bài toán nhân ma trận hay có thể rất phức tạp. Tuy
nhiên, trong những thuật toán song song cụ thể nào đó, đồ thị phụ thuộc tác
vụ cũng thể hiện cách ánh xạ vào trong các tiến trình. Trong mô hình đồ thị
tác vụ, mối tương giao giữa các tác vụ được sử dụng để gia tăng tính cục
bộ hay làm giảm đi chi phí tương tác. Mô hình này về cơ bản được sử dụng
để giải quyết những vấn đề mà trong đó dữ liệu đi theo các tác vụ là khá lớn
so với nội dung tính toán. Thông thường thì các tác vụ được ánh xạ tĩnh
nhằm giúp tối ưu chi phí cho việc di chuyển giữa chúng.
Các kỹ thuật làm giảm tương tác có thể áp dụng cho mô hình này
là giảm kích thước dữ liệu và tần số tương tác bằng cách gia tăng sử dụng
dữ liệu cục bộ, và sử dụng các phương pháp tương tác bất đồng bộ để thay
tương tác bằng các phép tính có lợi.
2.4.4.3. Mô hình Work Pool
Cách thức ánh xạ tĩnh các tác vụ vào trong các tiến trình nhằm cân bằng
tải là một tính chất tiêu biểu của mô hình work pool hay task pool, mà trong
đó nó có thể được thực hiện bởi bất kỳ tiến trình nào.
Trong mô hình truyền thông điệp, mô hình work pool về cơ bản thường
được sử dụng khi khối lượng dữ liệu đi theo các tác vụ là khá nhỏ so với nội
dung tính toán của chúng.
2.4.4.4. Mô hình Master-Slave
Trong mô hình master-slave hay manager-worker, một hay nhiều
tiến trình master sẽ phát sinh công việc và phân phối nó cho các tiến trình
con. Các tác vụ có thể đuợc xác định một thứ tự ưu tiên nếu tiến trình chính
Trang 50
có thể ước tính được kích thước của các tác vụ đó hay nếu phương pháp ánh
xạ ngẫu nhiên có thể thực hiện công việc cân bằng tải. Trong ngữ cảnh khác
các tác vụ có thể được gán những phần nhỏ hơn của công việc tại các thời
điểm khác nhau. Thông thường người ta sử dụng cách thứ hai nếu tiến trình
chính không mất quá nhiều thời gian để phát sinh công việc khiến các tiến
trình con phải chờ đợi. Trong nhiều trường hợp các công việc có thể theo
nhiều bước, và công việc trong mỗi bước phải được thực hiện xong trước
khi công việc của bước tiếp theo được phát sinh. Đối với những trường hợp
như vậy, thì tiến trình chính yêu cầu các tiến trình con phải thực hiện đồng
bộ sau mỗi bước. Mô hình manager-worker có thể được thể hiện theo cấu
trúc phân nhánh hay mô hình manager-worker nhiều tầng mà trong đó
manager ở cấp cao hơn sẽ truyền xuống các công việc cho manager ở cấp
dưới, cứ thế tiếp tục phân chia cho các worker thực hiện công việc của
mình.
Mô hình này nhìn chung thích hợp cho mô hình lập trình chia sẽ
không gian bộ nhớ và truyền thông điệp vì thường các tương tác là theo 2
chiều, nghĩa là tiến trình chính biết mình phải phân phối công việc còn tiến
trình con thì biết mình phải lấy gì từ tiến trình chủ.
Trong khi sử dụng mô hình master-slave, cần phải cẩn thận để
bảo đảm sao cho tại tiến trình chủ không xảy ra hiện tượng “cổ chai“, điều
này có thể xảy ra nếu các tác vụ được thực thi là quá nhỏ (hay các tiến trình
con làm việc quá nhanh).
2.4.4.5. Mô hình dây chuyền (pipeline) hay Producer-
Consumer
Trong mô hình dây chuyền, một dòng tin được truyền qua một
dãy liên tiếp các tiến trình, từng tiến trình sẽ thực hiện một vài tác vụ trên
đó. Quá trình thực thi đồng thời các chương trình khác nhau trên một dòng
tin được gọi là song song theo dòng (stream parallelism). Ngoại trừ tiến
trình khởi tạo đường ống, các dữ liệu mới tới sẽ kích hoạt một tiến trình
thực thi một tác vụ trên đường ống. Các tiến trình có thể tạo những đường
Trang 51
ống như vậy theo dạng tuyến tính hay mảng nhiều hướng, cây, hay các đồ
thị thông thường có hay không có vòng. Một đường ống (pipeline) là một
chuỗi của các producer và consumer. Từng tiến trình trong đường ống có
thể được xem như là người tiêu thụ cho một dãy các phần tử dữ liệu của tiến
trình trước đó và cũng là người sản xuất dữ liệu cho tiến trình tiếp theo
trong đường ống. Đường ống không nhất thiết là một chuỗi tuyến tính, mà
nó có thể là một đồ thị có hướng. Mô hình đường ống thường sử dụng ánh
xạ tĩnh các tác vụ vào trong các tiến trình.
2.4.4.6. Mô hình lai
Trong một vài trường hơp, có thể áp dụng nhiều hơn một mô hình
cho một vấn đề, dẫn đến tạo ra mô hình thuật toán lai. Một mô hình lai có
thể được kết hợp từ nhiều mô hình áp dụng theo dạng phân nhánh hay từ
nhiều mô hình áp dụng tuần tự cho các bước khác nhau của một thuật toán
song song. Trong nhiều trường hợp, một dạng biểu diễn của thuật toán có
thể có nhiều tính chất của nhiều hơn một mô hình thuật toán. Ví dụ như là
một phép tính chính có thể được thể hiện thành một đồ thị tác vụ, nhưng
mỗi nút của đổ thị có thể là một tác vụ cha được kết hợp từ nhiều tác vụ con
thích hợp cho mô hình song song dữ liệu hay dây chuyền. Thuật toán
Quicksort song song là một trong những áp dụng của mô hình lai.
Trang 52
Chương 3. Các môi trường hỗ trợ tính toán lưới
3.1. Giới thiệu
Mục tiêu chính của lập trình Grid là nghiên cứu về các mô hình lập
trình, các công cụ và các phương pháp nhằm hỗ trợ cho việc phát triển hiệu quả
các thuật toán và các chương trình hiệu năng cao trên môi trường lưới. Lập
trình lưới yêu cầu các kỹ năng và tính chất cao hơn so với lập trình tuần tự, và
thậm chí là lập trình song song và phân tán. Bên cạnh việc sắp xếp các thao tác
đơn giản trên những cấu trúc dữ liệu riêng, hay sắp xếp các thao tác phức tạp
trên những cấu trúc dữ liệu chia sẽ hay phân tán, một lập trình viên tính toán
lưới cần phải đảm nhiệm luôn việc quản lý tính toán trên môi trường. Bên cạnh
việc chỉ thực hiện các thao tác đơn giản, người lập trình lưới cũng phải thiết kế
tương tác giữa những dịch vụ từ xa, nguồn dữ liệu và tài nguyên phần cứng.
Mặc dù người ta có thể xây dựng các ứng dụng Grid với các công cụ lập trình
hiện tại, nhưng người ta vẫn đang đồng lòng nhất trí với nhau rằng hiện nay
chúng vẫn không đáp ứng hiệu quả để hỗ trợ cho việc xây dựng mã nguồn
Grid.
Các ứng dụng lưới thường có xu hướng động và không đồng nhất, bởi vì
chúng sẽ chạy trên các loại nguồn tài nguyên khác nhau với cấu hình thay đổi
khi thực thi. Những cấu hình động này có thể được thúc đẩy bởi sự thay đổi của
môi trường, ví dụ như thay đổi hiệu năng hay lỗi của phần cứng, v.v…Bất kể
nguyên nhân gì thì liệu một mô hình hay một công cụ lập trình nào đó có thể
làm cho các nguồn tài nguyên “hỗn tạp” ấy trở nên “gần gũi” với những người
lập trình hay không? che dấu các khác biệt đó trong khi vẫn cho phép người lập
trình quyền điều khiển trên các loại tài nguyên nếu có thể? Nhưng nếu có một
sự trừu tượng thích hợp được sử dụng thì liệu nó có được hỗ trợ, cung cấp bởi
các hệ thống thời gian thực?
Grid thường được sử dụng cho tính toán hiệu năng cao với quy mô lớn.
Để đạt được hiệu năng cao thì yêu cầu cần phải có một sự cân bằng giữa tính
toán và thông tin giữa các nguồn tài nguyên liên quan. Hiện tại thì chúng ta có
Trang 53
thể thực hiện điều này bằng cách quản lý tính toán, thông tin, và dữ liệu cục bộ
sử dụng truyền thông điệp (message passing) hay gọi yêu cầu các phương thức
từ xa (remote method invocation - RMI).
Để giải quyết các vấn đề này, chúng ta phải biết được rằng các mô hình
lập trình hiện nay đang thiếu những gì, cần thêm những khả năng mới gì, và nó
sẽ được thực thi ở mức ngôn ngữ, mức công cụ hay ở hệ thống thời gian thực
nào. Thuật ngữ mô hình lập trình ở đây được sử dụng không chỉ liên quan đến
ngôn ngữ lập trình. Một mô hình lập trình có thể được thể hiện theo nhiều dạng
khác nhau, ví dụ như một ngôn ngữ, một thư viện API, hay đơn thuần chỉ là
một công cụ có các chức năng mở rộng. Một mô hình lập trình thành công nhất
là mô hình có hiệu năng cao, sự kết hợp và quản lý linh hoạt các nguồn tài
nguyên. Các mô hình lập trình cũng phải ảnh hưởng đến toàn bộ chu trình phát
triển phần mềm : thiết kế, cài đặt, kiểm lỗi, vận hành, duy trì, v.v…Vì thế
những mô hình thành công cũng phải đáp ứng việc sử dụng hiệu quả tất cả các
loại công cụ phát triển, ví dụ như là trình biên dịch, trình sửa lỗi, trình theo dõi
hiệu năng…
Trước tiên ta sẽ tìm hiểu các vấn đề chính khi lập trình lưới, sau đó
chúng ta sẽ tìm hiểu một vài mô hình lập trình phổ biến đang được sử dụng và
đề xuất trên môi trường Grid. Tiếp theo chúng ta sẽ thảo luận các phương pháp
và kỹ thuật lập trình nhằm giải quyết các vấn đề phức tạp bằng cách sử dụng
các công cụ đang có hiện nay.
3.2. Các vấn đề khi lập trình luới
3.2.1. Tính mang chuyển, tính khả thi và khả năng thích ứng
Các ngôn ngữ lập trình cấp cao hiện nay cho phép người dùng viết mã
nguồn hoàn toàn độc lập với bộ xử lý. Các mô hình lập trình lưới cũng nên có
khả năng như vậy. Điều này đối với các máy ảo thông dịch nghĩa là độc lập về
kiến trúc, nhưng nó cũng có nghĩa là khả năng sử dụng các đoạn mã nguồn hay
dịch vụ ở nhiều nơi khác nhau để cung cấp thành một chức năng tương tự. Tính
Trang 54
khả chuyển như vậy là một điều kiện tiên quyết cho việc sao chép các cấu hình
động và không đồng nhất.
Việc sử dụng những đoạn mã nguồn và dịch vụ khác nhau nhưng có
chức năng tương tự nhau thể hiện tính cộng tác trong việc thi hành các mô hình
lập trình. Khái niệm về một kiến trúc Grid mở và có tính mở rộng ngụ ý là một
môi trường phân tán có thể hỗ trợ cho các giao thức, dịch vụ, giao diện lập
trình ứng dụng và các công cụ phát triển phần mềm. Cuối cùng tính mang
chuyển và tính cộng tác sẽ dẫn đến khả năng thích ứng. Một chương trình Grid
phải có khả năng thích ứng với các cấu hình khác nhau dựa trên nguồn tài
nguyên sẵn có. Điều này có thể xảy ra vào thời điểm bắt đầu, hay tại thời điểm
thực thi nguyên do sự thay đổi các yêu cầu của ứng dụng hay do khả năng phục
hồi lỗi. Khả năng thích ứng như vậy có thể liên quan đến một bước khởi động
lại đơn giản ở đâu đó hay là một sự tích hợp thật sự giữa tiến trình và dữ liệu.
3.2.2. Khả năng phát hiện tài nguyên
Tìm ra các tài nguyên hiện có trên mạng là một phần quan trọng của tính
toán lưới. Mã nguồn của chương trình lưới sẽ chỉ ra rõ ràng những máy (host)
thích hợp nào để chạy chương trình. Tuy nhiên bởi vì Grid chứa đựng nhiều
dịch vụ cố định, nên chúng cũng vẫn phải có khả năng tìm ra các dịch vụ này
và các giao diện mà chúng hỗ trợ. Cách sử dụng các dịch vụ này phải có khả
năng tái lập trình và kết hợp lại theo một cách thống nhất. Vì thế môi trường và
công cụ lập trình phải chú ý tìm ra các dịch vụ hiện có và cung cấp cho người
dùng các cách thức tường minh hay ngầm ẩn để khai thác chúng trong quá trình
xây dựng và triển khai các ứng dụng Grid.
3.2.3. Hiệu năng
Rõ ràng đối với nhiều ứng dụng Grid, vấn đề hiệu năng là điều rất đáng
quan tâm. Bởi vì Grid sử dụng băng thông hỗn tạp và các hệ thống phân cấp ẩn
cho nên điều này gây khó khăn cho việc đạt được hiệu năng tốt nhất và cách sử
dụng hiệu quả các nguồn tài nguyên.
Trang 55
Tuy nhiên đối với nhiều ứng dụng, để đạt hiệu năng đáng tin cậy cũng là
một vấn đề khá quan trọng. Một môi trường động và không đồng nhất có thể
tạo ra nhiều khả năng thực thi khác nhau mà có thể sẽ không được chấp nhận
trong nhiều tình huống. Vì thế trong môi trường chia sẽ, chất lượng dịch vụ sẽ
trở nên càng cần thiết nhằm đạt được hiệu năng đáng tin cậy trên một cấu hình
tài nguyên đã cho. Trong khi người dùng có thể yêu cầu mô hình theo một hiệu
năng nào đó, tuy nhiên sẽ hợp lý hơn nếu hiệu năng cung cấp nằm bên trong
một khoảng giới hạn nào đó.
3.2.4. Dung lỗi
Việc cần có nhiều cấp độ dung lỗi trong môi trường Grid là hoàn toàn
cần thiết. Điều này đặc biệt đúng khi các ứng dụng khởi tạo hàng ngàn các
công việc độc lập tương tự với nhau trên hàng ngàn máy trạm (host). Rõ ràng
khi số lượng các tài nguyên tham gia tính toán ngày càng tăng thì cũng làm gia
tăng xác suất bị hỏng. Các chương trình Grid phải có khả năng kiểm tra các lỗi
khi đang thực thi, và bên cạnh đó cũng phải cung cấp khả năng phục hồi và
phản ứng khi có lỗi xảy ra ở cấp độ chương trình. Tại thời điểm đó các công cụ
cũng phải bảo đảm cho các phép tính cũng được thực thi ở cấp độ tối thiểu khi
có lỗi xảy ra.
3.2.5. Bảo mật
Chúng ta sẽ còn tiếp tục chứng kiến sự phát triển của tính toán lưới trên
nhiều domain chia sẽ, như là các mạng. Trong khi việc cung cấp một chức năng
chứng thực mạnh giữa hai site là cực kỳ quan trọng, thì bên cạnh đó việc quản
lý chương trình trên nhiều site cũng là điều không đơn giản. Vì thế, một
phương pháp bảo mật có cấp khả năng xác thực người dùng phải được tích hợp
vào trong các mô hình lập trình lưới.
3.2.6. Các siêu mô hình
Phương pháp lập trình truyền thống với các ngôn ngữ lập trình cổ điển
dựa vào trình biên dịch để thực hiện việc chuyển đổi giữa 2 mô hình lập trình,
như là giữa ngôn ngữ cấp cao C hay Fortran, với tập các chỉ thị phần cứng thể
Trang 56
hiện bởi việc thực thi tuần tự các hàm trên dữ liệu trong bộ nhớ. Quá trình
chuyển đổi này có thể là sự xây dựng của một số các mô hình liên quan đến
ngữ nghĩa của mã nguồn và sự áp dụng một số tính năng cải tiến như tối ưu,
dọn dẹp bộ nhớ, và kiểm tra phạm vi. Sự kết hợp các siêu mô hình tương tự sẽ
góp phần xây dựng chương trình Grid.
3.3. Tổng quát về các môi trường hỗ trợ
3.3.1. Một số môi trường Grid
3.3.1.1. NetSolve
NetSole là một ứng dụng client/server đuợc thiết kế để giải quyết những
vấn đề tính toán khoa học trong môi trường phân phối.
Agent
Agent
Network of servers Client
Client
MPP servers
Scalarserverrequest
choice
reply
Hình 3-1 : Mô hình NetSolve
Hệ thống Netsolve dựa trên những hệ thống phân phối, được kết nối
thông qua mạng LAN hay WAN. Những chương trình từ máy khách Netsolve
có thể được viết bằng C hay FORTRAN, và sử dụng Web để giao tiếp với
Server. Một server Netsolve có thể sử dụng một số gói phần mềm liên quan đến
khoa học để cung cấp cho những phần mềm tính toán. Những giao tiếp truyền
thông bên trong Netsolve thông qua những socket. Netsolve đáp ứng những
khả năng cho việc tìm kiếm những tài nguyên máy tính trên một mạng máy
Trang 57
tính, chọn những tài nguyên sẵn dùng tốt nhất, giải quyết một vấn đề, và trả kết
quả cho người sử dụng.
3.3.1.2. Legion
Là một hệ thống trên cơ sở đối tượng được phát triển ở đại học Virginia
(Hoa Kỳ). Legion cung cấp kiến trúc phần mềm để hệ thống những máy tính
phân phối khắp nơi, với số lượng khổng lồ có thể giao tiếp với nhau một cách
dễ dàng. Trong hệ thống Legion, có những đặc điểm sau sau:
- Mọi thứ là một đối tượng. Những đối tượng đặc trưng cho tất cả các
phần cứng và phần mềm. Mỗi đối tượng là một xử lý hoạt động, đáp ứng
những yêu cầu giải pháp cho những đối tượng khác bên trong hệ thống. Legion
định nghĩa một tập API cho việc giao tiếp đối tượng. Nhưng không phải là
ngôn ngữ lập trình hay giao thức truyền thông.
- Những lớp quản lý những trường hợp. Mọi đối tượng Legion được
định nghĩa và quản lý bởi chính đối tượng hoạt động .Những lớp đối tượng có
những khả năng như sau: tự tạo một trường hợp thể hiện (instance), lập biểu
cho việc thực thi, làm cho một đối tượng khác hoạt động, hay không hoạt động,
và cung cấp thông tin về trạng thái cho những đối tượng thuộc về các máy tính
khác.
Những người dùng có thể định nghĩa thêm các lớp mới. Giống ngôn ngữ
lập trình hướng đối tượng, người dùng có thể định nghĩa lại hay viết lại những
chức năng của một lớp. Đặc điểm này cho phép những chức năng này có thể
thêm, hay xoá tùy theo nhu cầu của người dùng.
Hệ thống Legion hỗ trợ một tập các dạng đối tượng cốt lõi :
• Những lớp và lớp tự định nghĩa
• Những đối tượng chủ : Những đối tượng chủ là sự trừu tượng hóa
của việc xử lý những tài nguyên, chúng có thể thể hiện một bộ xử lý
đơn hay nhiều máy tính hay mhiều bộ xử lý.
3.3.1.3. Globus
Trang 58
Globus cung cấp một cơ sở hạ tầng phần mềm, làm cho những ứng dụng có
thể quản lý phân phối những tài nguyên tính toán khổng lồ như một máy tính
đơn ảo.
Một Grid, là một cở sở hạ tầng phần cứng và phần mềm, cung cấp truy xuất các
tài nguyên khắp nơi dùng cho tính toán cấp cao, dù cho sự phân phối thuộc về
địa lý của tài nguyên và người sử dụng có sự cản trở. Globus cung cấp những
dịch vụ cơ bản và những khả năng được yêu cầu để cấu trúc một mạng tính
toán lưới. Bộ công cụ bao gồm một tập hợp các thành phần bổ sung cho những
dịch vụ cơ bản, chẳng hạn như bảo mật, định vị tài nguyên, quản lý tài nguyên,
và dịch vụ truyền thông.
Mạng tính toán lưới được hỗ trợ một số lượng lớn những ứng dụng và
mô hình lập trình, đó là một điều thiết yếu.Vì thế, việc cung cấp hơn một mô
hình lập trình chuẩn, chẳng hạn như mô hình lập trình hướng đối tượng là điều
thiết yếu. Globus cung cấp một số dịch vụ cho phép những nhà phát triển công
cụ đặc biệt hay những ứng dụng có thể sử dụng để tạo ra những yêu cầu cụ thể
cho chính họ. Phương pháp này chỉ khả thi khi những dịch vụ có sự khác biệt
và được định nghĩa tốt thông qua những tập API của nó, Globus được kiến tạo
như một tầng kiến trúc với những dịch vụ cấp cao được xây dựng trên những
dịch vụ cốt lõi ở tầng thấp hơn. Bộ công cụ Globus được phân thành những mô
đun, và một ứng dụng có thể khai thác những đặc điểm này của từng mô đun
của Globus, chẳng hạn như sự quản lý tài nguyên hay hạ tầng thông tin, mà
không sử dụng những thư viện truyền thông của Globus. Bộ công cụ Globus hỗ
trợ những dịch vụ sau :
• GSI (Grid Security Infrastructure): kiến trúc bảo mật
• GridFTP: giao thức truyền tập tin
• GRAM (Globus Resource Allocation Manager): quản lý các tài nguyên
trên môi trường Grid.
• Metacomputing Directory Service
• Globus Access to Secondary Storage
• Data catalogue và replica management
Trang 59
• Advanced Resource Reservation và Allocatoin(GARA)
Hình 3-2 : Các thành phần của Globus
Globus có thể được nhìn nhận như một hệ thống cơ bản cho tính toán
lưới, ngoài việc cung cấp cho nhà phát triển ứng dụng một tập thư viện API đặc
trưng cho các dịch vụ Globus mà cung cấp. Globus còn cung cấp cho những
nhà phát triển ứng dụng một phương tiện hiện thực cho việc bổ sung các dịch
vụ để cung ứng cho môi trường thực thi ứng dụng trên một vùng rộng lớn.
3.3.2. Những mô hình lập trình và công cụ hỗ trợ
Cho đến lúc này, gần 20 năm nghiên cứu và phát triển trong ngành lập
trình song song và phân bố. Việc thiết kế hệ thống phân bố đã hướng nền phát
tiển kỹ thuật phần cứng lên một tầm cao mới và ước hẹn có thể xây dựng được
hệ thống tốt, cải thiện được trạng thái hiện thời và sử dụng lại hệ thống. Sự
phát triển Grid computing cũng lấy gốc từ việc tính toán song song và phân bố
này, bởi vì chúng đã xác lập được những phương pháp lập trình nền tảng cho
sự phân bố và song song hoá .Chúng em sẽ đưa ra một số mô hình lập trình và
công cụ mà ngày nay đã được thực nghiệm trên thế giới
3.3.2.1. Mô hình chia sẽ trạng thái
Trang 60
Mô hình lập trình Shared-state đặc trưng cho sự liên kết chặt chẽ ,những
ngôn ngữ đồng bộ và những mô hình thực thi cho những máy tính chia sẻ bộ
nhớ và hệ thống mạng chia sẻ vùng nhớ giữa các máy tình, với băng tầng
truyền thông cao và độ trễ trong việc truyền thông thấp. Việc này quyết định
môi trường Grid và sẽ làm tác động đến các công cụ lập trình khác trở nên
không hiệu quả, vì thế cần có một số mô hình lập trình thiết yếu dựa trên hình
thức chia sẻ trạng thái, và như thế trình sản xuất và tiêu thụ dữ liệu giữa các
tiến trình được phân chia rõ ràng hơn trên môi trường Grid.
• JavaSpaces
Javaspaces là một sự bổ sung dựa trên Java với khái niệm không gian
biến (tuplespace) Linda, điều này được minh hoạ bằng một tập biến được thể
hiện bởi một tập các đối tượng. Sử dụng Java có đặc điểm là nhiều client và
server tương tác với nhau mà không liên quan đến những kiến trúc của bộ xử lý
và hệ điều hành. Sử dụng JavaSpaces nhìn nhận một ứng dụng như một tập
những xử lý giao tiếp với nhau bằng cách nhận và đưa những đối tượng vào
một hay nhiều vùng không gian (space). Một không gian (space) là một kho
chứa đối tượng cụ thể và được chia sẻ và được truy xuất thông qua mạng máy
tính. Những xử lý sử dụng kho chứa như một kỹ thuật trao đổi dữ liệu thay vì
phải giao tiếp trực tiếp với nhau. Những thao tác chính là một xử lý có thể có
một không gian để đặt, nhận, đọc, sao chép những đối tượng .Trên thao tác
nhận hay đọc, đối tượng nhận được xác định bởi một thao tác có tính chất kiểm
tra sự gần giống liên kết (associative matching ). Sự gần giống này gồm dạng
và số lượng thành phần liên kết với đối tượng đặt vào không gian. Một lập trình
viên muốn xây dựng một ứng dụng trên nền tảng như thế này nên thiết kết cấu
trúc dữ liệu phân phối giống như một tập những đối tượng được lưu trữ trong
một hay nhiều không gian.
Sự tiếp cận mới mà mô hình lập trình JavaSpace mang lại cho lập trình
viên là xây dựng những ứng dụng phân phối dễ dàng hơn trên môi trường Grid.
Hiện thời thì việc viết ứng dụng đựa trên JavaSpace được hỗ trợ trên
Grid sử dụng công cụ Java của Sun cho Globus.
3.3.2.2. Mô hình truyền thông điệp (Message Passing)
Trang 61
Trong những mô hình truyền thông điệp, những tiến trình được phân
chia riêng không gian bộ nhớ, và thông tin trao đổi bằng cách truyền thông điệp
từ một tiến trình đến các tiến trình còn lại. Sự song song hoá thể hiện rõ ràng
bằng các thông điệp, nó mang lại cho người sử dụng đầy đủ quyền điều khiển
tiến trình mà những mô hình lập trình khác không có.
• MPI và những biến thể của nó:
MPI (Message Passing Interface) là một chuẩn rất phổ biến cho lập trình
truyền thông điệp. Trong phần sau chúng em sẽ mô tả kỹ hơn.
MPCH-G2 là một sự bổ sung của chuẩn thư viện MPI cho Grid, sử dụng
những dịch vụ của Globus và cho phép lập trình viên kết nối nhiều máy tính
với kiến trúc khác nhau để chạy ứng dụng MPI.
MPICH-G2 tự động chuyển đổi dữ liệu trong những thông điệp được
gửi giữa những máy tính với kiến trúc khác nhau và hỗ trợ truyền thông đa giao
thức bằng cách tự chọn giao thức mạng TCP cho việc truyền thông điệp giữa
các máy tính với nhau.
Sư phổ biến của MPI kéo theo sự xuất hiện một số những biến thể của
nó, liên quan đến những vấn đề của Grid như tự động hoá quản lý tiến trình, và
nhiều thao tác hiệu quả liên quan đến nhiều tiến trình.
Ví dụ thư viện MagPIe là một sự bổ sung cho những thao tác liên quan
đến nhiều tiến trình (collective operation) của MPI chằng hạn như phân bố dữ
liệu dạng broadcast, đồng bộ các tiến trình, và những toán tử tính toán gộp với
sự tối ưu hoá về thuật toán cho những hệ thống rộng lớn như Grid. Những thao
tác này sẽ được nói đến chi tiết trong phần lập trình MPI tiếp theo.
Stampi hỗ trợ trình quản lý tiến trình tự động, MPI-IO và MPI-2.
MPI_Connect hỗ trợ cho những ứng dụng MPI khác nhau, của các nhà phân
phối MPI khác nhau có thể giao tiếp được với nhau.
3.3.2.3. Mô hình RPC và RMI
Trong những mô hình truyền thông điệp (Message Passing), hình thức
truyền thông tồn tại là các hình thức truyền thông như điểm điểm, một điểm
đến nhiều điểm, v.v...
Trang 62
Những trình gửi thông điệp đều có những thông số thiết yếu cho những
trình nhận thông điệp để xác định thông điệp này, và quyết định xử lý thông
điệp hay không dựa trên dạng thông điệp. Ngữ nghĩa liên quan đến dạng thông
điệp thường được định nghĩa bởi các nhà thiết kế ứng dụng. Những hình thức
gọi hàm từ xa RPC (Remote Procedure Call) và cung cấp phương thức từ xa
RMI (Remote Method Invocation) cung cấp những khả năng như thế này.
Những cấu trúc giao tiếp giữa trình gửi và trình nhận giống như là một ngôn
ngữ hơn là những lời gọi hàm thư viện đơn giản chỉ di chuyển dữ liệu giữa
nhiều điểm A và B của mô hình truyền thông điệp.
Những mô hình RPC và RMI cung cấp một kỹ thuật đơn giản và dễ
hiểu cho sự quản lý tính toán từ xa. Ngoài chức năng là một kỹ thuật cho quản
lý các dòng điều khiển và dữ liệu. RPC và RMI còn cho phép kiểm tra các dạng
tham số và số lượng tham số. RPC và RMI có thể được dùng để xây dựng
những mô hình cấp cao hơn cho Grid, như những thành phần, những dịch vụ
mạng v.v...
• RPC hướng Grid
GridRPC là một mô hình RPC và là thư viện API cho Grid. Bên cạnh
cung cấp ngữ nghĩa chuẩn RPC còn cung cấp sự thực thi bất đồng bộ, song
song các tác vụ v.v..
Ba khả năng rất quan trong mà GridPRC cung cấp cho người sử dụng
cái nhìn trong suốt về cách quản lý tiến trình như sau:
+ Tìm kiếm và lập biểu tự động cho tài nguyên (Dynamic resoure
discovery and scheduling). Những dịch vụ RPC có thể được đặt bất kỳ ở đâu
trên Grid. Tìm kiếm, lựa chọn, và lập biểu cho sự thực thi từ đằng xa được
thực hiện dựa trên những ràng buộc,những yêu cầu cơ bản của người sử dụng.
+ Bảo mật (security): Bảo mật Grid thông qua GSI và chứng thực X.509
là điều cần thiết cho hệ điều hành trong một môi trường mở. Globus là công
cụ Grid hỗ trợ bảo mật này .
+ Khả năng dung lỗi (Fault tolerance): Thông qua việc kiểm tra các nút,
giảm thiểu hay chạy lại các ứng dụng trên các nút nhằm bảo đảm độ tin cậy
ngày càng trở nên thiết yếu cùng với số lượng tài nguyên liên quan tăng lên.
Trang 63
Trình quản lý giao tiếp là một vấn đề quan trọng cho tất cả các mô hình
gọi hàm từ xa (RPC). Điển hình là một ngôn ngữ định nghĩa giao tiếp
(Interface Definition Languague IDL). Và như thế GridRPC cũng được thiết
kế với một số những thuộc tính trong trường hợp cải thiện khả năng dùng lại
và dễ bổ sung và triển khai:
+ Hỗ trợ cho một ngôn ngữ đăc tả giao tiếp cụ thể: Bao gồm nhiều tham
số dạng ma trận, những tham số dạng ma trận chia sẻ bộ nhớ, tham số tập tin,
và những tham số này đều được gọi tham chiếu qua hàm.
+ Quản lý ngôn ngữ đặc tả giao tiếp ở máy chủ: Chỉ có những máy chủ
GridRPC quản lý và giám sát tiến trình tác vụ. Máy khách có nhiệm vụ đơn
giản hơn ,chỉ thực thi tiến trình.
• Java RMI
Những phương thức Java được cung cấp từ xa làm cho những lập trình
viên có thể tạo những ứng dụng phân phối dựa trên ngôn ngữ lập trình Java.
RMI thừa kế thiết kế từ RPC cơ bản, nhưng nó có những đặc điểm phân biệt
với RPC cơ bản. Với RMI, một chương trình chạy trên máy ảo Java có thể yêu
cầu những phương thức của những đối tượng khác bên trong các máy ảo khác.
Thuận lợi chính của RMI là mô hình hướng đối tượng thực sự, hỗ trợ tất cả các
dạng dữ liêu của một chương trình Java, và có sự hỗ trợ thu gom rác của
chương trình. Do đó Java RMI cung cấp một giao diện lập trình cấp cao, rất
thích hợp cho tính toán lưới.
3.3.2.4. Mô hình hỗn hợp
Sự tự nhiên của tính toán lưới là tạo ra tất cả các nguồn tài nguyên máy
tinh được sẵn dùng trong ứng dụng Grid. Vì thế, một số ứng dụng sẽ muốn
thực thi cả bên trong và xuyên suốt không gian địa chỉ. Thực thi nhiều tiểu
trình trong cùng một không gian địa chỉ được phân phối, và cũng thông qua dữ
liệu và điều khiển giữa các máy tính. Ví dụ như tình trạng xảy ra đối với một
nhóm nhiều bộ xử lý cân bằng và bên trong Grid.
OpenMP và MPI
OpenMP là một thư viện hỗ trợ lập trình song song trong những máy
tính chia sẻ bộ nhớ. Thư viện này được phát triển bởi một tổ chức những nhà
Trang 64
cung cấp với những mục tiêu của việc sản xuất một giao tiếp lập trình chuẩn
cho những máy tính chia sẻ bộ nhớ song song, và sử dụng những ngôn ngữ như
Fortran, C và C++. OpenMP cho phép những đoạn mã thực thi song song
(vòng lập DO song song), định nghĩa dữ liệu chia sẻ (SHARED) và đồng bộ
hoá các xử lý.
3.3.2.4. Mô hình Peer-to-Peer
Tính toán peer – peer là sự chia sẻ của những tài nguyên máy tính và
những dịch vụ bằng cách trao đổi trực tiếp giữa các hệ thống.
• JXTA
Một họ những giao thức thiết kế đặc biệt cho tính toán P2P là JXTA.
Tên JXTA được trích dẫn từ “juxtapose” và có nghĩa đơn giản như hình thức
tính toán P2P, client/server và tính toán dựa trên Web. Như vậy, JXTA là một
tập hợp những giao thức tổng quát P2P, được định nghĩa trong những thông
điệp XML, cho phép một số thiết bị đã kết nối trên mạng sắp xếp từ những máy
điện thoại di động (cell phone) và những thiết bị máy tính bỏ túi (PDA) đến
những máy tính (PC) và máy chủ (server) để giao tiếp và làm việc với nhau ở
hình thức P2P.
3.3.3. Môi trường cài đặt
3.3.3.1. Tồng quan
Chúng em đã thử cài đặt Globus phiên bản 3.2 nhưng hiệu quả cài đặt
không cao. Việc cài đặt và lập trình trên máy đơn hầu như đơn giản, chỉ cần vài
thao tác có thể xong. Nhưng việc cài đặt trên một mạng LAN thì khó khăn
trong việc thông nhau giữa các máy sử dụng Globus.
Chúng em quyết định sử dụng môi trường lập trình truyền thông điệp
LAM/MPI.
Là phiên bản nguồn mở, cung cấp miễn phí với chuẩn MPI. LAM/MPI
được nghiên cứu, phát triển và hỗ trợ bởi phòng thí nghiệm hệ thống mở (Open
Systems Lab) ở trường đại học Indiana. LAM/MPI hỗ trợ tất cả các chuẩn
MPI-1 và nhiều chuẩn MPI-2.
Trang 65
LAM/MPI không chỉ là thư viện bổ sung các hàm API của MPI ,mà còn
là môi trường thực thi LAM: 1 tầng người dùng, môi trường nền tảng trung
gian, nó cung cấp nhiều dịch vụ cho những chương trình MPI. Cả những thành
phần chính của LAM/MPI được thiết kế như những thành phần có chức năng
riêng biệt, có khả năng mở rộng với những mô đun vào lúc thi hành. Thành
phần này được biết như là Hệ thống Giao tiếp Dịch vụ (System Services
Interface _SSI).
3.3.3.2. Cài đặt
o Những yêu cầu chung
Hệ điều hành:
LAM/MPI được sử dụng trên Linux. Mặc dù MPI/MPI được thử nghiệm
trên Red Hat và hệ thống Mandrake Linux sử dụng phiên bản kernel hiện tại
nhưng nó vẫn chay tốt trên các phiên bản Linux phân phối khác.
Các phiên bản Linux cũ hơn như kernel phiên bản 2.2.0 đến 2.2.9 có vài
lỗi trong vấn đề mạng TCP/IP. Phiên bản 2.2.10 đã sửa được các vấn đề này.
Vì thế các bạn có thể nâng cấp phiên bản Linux lên 2.2.10 hay mới hơn để việc
cài đặt và thực hiện chương trình LAM/MPI được chắc chắn hơn.
Phiên bản Linux nhóm chúng em chọn sử dụng là RedHat 10 core 1, và
các phiên bản Linux 9.
Trình biên dịch trên hệ điều hành
Trình biên dịch ANSI C
Trình biên dịch C++ có hỗ trợ namespace
Các tiện ích Unix shell như sed, awk,và grep v.v. hay các tiện ích của
Linux như emacs, gedit, terminal v.v...
o Những yêu cầu của mô đun dịch vụ hệ thống
Như đã nói LAM/MPI được xây dựng xung quanh một thành phần kiến
trúc cốt lõi được biết như Hệ thống giao tiếp dịch vụ (System Services
Interface _SSI). Một trong những nguyên tắc chủ yếu là khả năng thực hiện
“cắm chạy” (plug-in) lúc thực thi để mở rông khả năng các mô đun của LAM.
Trang 66
Mỗi mô đun thành phần được chọn từ mỗi loại lúc thực thi và được sử
dụng để thực hiện hiệu quả môi trường LAM và thư viện MPI (Xem chi tiết
trong chuẩn lập trình song song MPI)
Hiện thời LAM/MPI sử dụng 4 dạng thành phần mô đun
boot: bắt đầu môi trường thực thi LAM, được sử dụng với
dòng lệnh lamboot
coll: quản lý những hàm MPI truyền thông đa xử lý, sử dụng
bên trong xử lý MPI.
cr: kkhởi động lại những chức năng , được sử dụng bên trong
xử lý MPI và dòng lệnh LAM
rpi: quản lý những hàm MPI truyền thông điểm điểm, chỉ sử
dụng bên trong xử lý MPI
Mỗi mô đun hệ thống giao tiếp dịch vụ có cấu hình chính và xây dựng
hệ thống phụ. Một số mô đun cấu hình bị lỗi sẽ có thể bỏ qua và không gây ra
việc cài đặt bị lỗi, giống như cài đặt chương trình nào đó mà ta bấm qua nút
Skip.
Mỗi SSI mô đun có thể có những yêu cầu cho việc cài đặt thêm, ngoại trừ
những yêu cầu chung của LAM.
Chi tiết các mô đun ở trên :
Bproc Boot: chỉ được kiểm thử với tập hợp 3.2.x với phiên
bản v3.2.5. Những phiên bản trước đó của 3.2.x bị lỗi và có
thể gây cho LAM/MPI hỏng khi đang chaỵ.
SLURM Boot: hỗ trợ việc thực thi trong những môi trường
SLURM. Không cấu hình bổ sung hay xây dựng những tham
số là cần thiết cho việc hỗ trợ SLURM. Dòng lệnh laminfo có
thể được sử dụng để xác nhận lại rằng mô đun boot slurm sẵn
có trong gói việc cài đặt LAM
Các mô đun còn lại có thể tham khảo thêm
TM Boot
BLCR Checkpoint /Restart
Myrinet (gm) RPI
Trang 67
Infiniband(ib) RPI
Shared Memory RPI
o Cấu hình LAM/MPI
Bước đầu tiên và cũng là phức tạp nhất trong việc cài đặt LAM/MPI là
cấu hình xử lý. Nhiều lựa chọn có thể được thiết lập lúc cài đặt hay khi thực thi
chương trình, việc cấu hình đơn giản chỉ để trạng thái mặc định
Các bước trong việc cài đặt :
Giải nén
Phiên bản phân phối LAM được đóng gói như một tập tin được nén có định
dạng gzip hay bzip2.
shell$ gunzip –c lam-7.1.tar.gz|tar xf
shell$ tar zxf lam-7.1.tar.gz
Những cấu hình cơ bản :
LAM sử dụng một đoạn script cấu hình GNU để hiển thị các trang cài
đặt và đặt tả các cấu hình:
Chuyển đường dẫn tới thư mục chứa tập tin Lam đã được giải nén. Thiết
lập các biến môit trường cần thiết và thực thi tập tin script configure
shell$cd lam-7.1
shell$ ./configure <tuỳ chọn>
Mặc định thì tập tin script configure thiết lập thư mục cài đặt LAM ở
thư mục cha nơi mà dòng lệnh lamclean được tìm thấy ,hay đường đẫn
/usr/local nếu dòng lệnh lamclean không tìm thấy .Cách cài đặt như thế này có
thể được chồng lắp với tuỳ chọn –prefix
Tuỳ chọn trình biên dịch :
Đoạn mã trong tập tin configure tìm kiếm các trình biên dịch đúng cho việc xây
dựng LAM/MPI
Tuỳ chọn trình biên dịch
Đặc tả trình biên dịch và những tuỳ chọn trình biên dịch
Những biến môi trường được sử dụng để chồng lắp lên những thông số
đã cài đặt mặc định
Trang 68
Trình biên dịch: những biến môi trường CC, CXX, và FC đặc tả trình
biên dịch C, C++ và Fortran được sử dụng để xây dựng LAM. Dòng lệnh tương
ứng sẽ là mpicc, mpic++ và mpiff7
Những cờ biên dịch: những biến môi trường CFLAGS, CXXFLAGS, và
FFFLAGS đặc tả những cờ biên dịch để thông qua các trình biên dịch thích
hợp. Những cờ này chỉ được sử dụng khi xây dựng LAM và không được thêm
vào những danh sách tham số của trình biên dịch có tính chất như vỏ bọc bên
ngoài chẳng hạn như mpicc, mpic++. Các trình biên dịch này được gọi như vậy
bởi vì nó bao bọc một trình biên dịch bên trong, chẳng hạn như trình mpicc bao
bọc trình biên dịch gcc, trình mpic++ bao bọc trình gc++ v.v...
Những cờ liên kết: những biến môi trường như LDFLAGS,
CXXLDFLAGS được sử dụng để thêm những tham số vào trình liên kết (hay
trình biên dịch C++ khi sử dụng một trình liên kết). Chúng cũng không được
thêm vào danh sách tham số của trình biên dịch có tính chất như vỏ bọc bên
ngoài các trình biên dịch khác
Tuỳ chọn cấu hình :
Đoạn mã cấu hình trong tập tin configure sẽ tạo một số tập tin cấu hình
sử dụng trong suốt pha xây dựng LAM. Bao gồm những tập tin dùng để định
nghĩa như /share/include/lam_config.h.
Những tuỳ chọn tổng quát :
Những tuỳ chọn sau đây liên quan đến những kiến trúc cơ bản
LAM/MPI:
o --disable-static :
Không xây dựng các thư viện tĩnh. Cờ trạng thái này chỉ có nghĩa khi
–enalble-shared được thiết lập, nếu cờ này được đặc tả mà enable-shared không
thiết lập thì nó coi như được bỏ qua và thư viện tĩnh được tạo ra.
o --enalble-shared: xây dựng thư viện được chia sẻ .
o --prefix=PATH: thiết lập thư mục cài đặt cho những tập tin nhị
phân, thư viện, v.v.. của LAM là PATH. PATH phải được đặt tả
như một tên thư mục cố định
o --with-boot=MODULE_NAME
Trang 69
MODULE_NAME được thiết lập mô đun SSI khởi động (SSI
boot) mặc định. MODULE_NAME phải là một trong những kỹ
thuật khởi động liên thông các máy trên mạng với nhau. Hiện
thời, những kỹ thuật này bao gồm: rsh, tm, slurm, và bproc, và
globus
Gía trị mặc định cho tuỳ chọn này là rsh. Chú ý rằng cấu hình
của LAM / xây dựng hệ thống sẽ cố gắng xây dựng những mô
đun RPI sẵn dùng.
o Xây dựng LAM
Một khi đã hoàn thành bước cấu hình ,tiếp theo là tạo dựng nên môi
trường LAM
shell$make
shell$make install
shell$make all install
Thay đổi thư mục cài đặt
LAM xây dựng hệ thống là khả năng của việc cài đặt vào một thư
mục một khi đặc tả bằng tuỳ chọn cấu hình –prefix. LAM sẽ không thực thi
một cách chắc chắn khi được cài đặt trong thư mục chuyển đổi. Tuy nhiên đặc
điểm này là hữu ích cho việc xây dựng những gói nhị phân .
Bổ sung những ví dụ có sẵn trong môi trường LAM/MPI
LAM bao gồm 2 gói ví dụ: những ví dụ LAM nói chung và những ví dụ
ROMIO. Cả hai gói này có thể được xây dựng từ một tầng đơn giản là “make
lamexamples”. Chú ý rằng, những ví dụ chỉ có thể được xây dựng sau khi đã
thành công trong việc tạo môi trường LAM ở trên và biến môi trường PATH đã
được thiết lập ($PATH=$prefix/bin)
3.3.3.3. Hướng dẫn sử dụng
• Khởi tạo môi trường
Trước khi những chương trình MPI được thực thi ,thì môi trường LAM phải
được khởi động .
Tập tin Boot (“Hostfile ,Machinefile”): quản lý tất cả các máy
trên mạng, để tạo thành một hệ LAM
Trang 70
Khi sử dụng giao thức tuyền tập tin trên Linux là rsh hoặc ssh để
khởi động LAM, phải cần một tập tin dạng văn bản liệt kê danh
sách những tên máy được LAM khởi động. Tập tin này điển hình
đựơc xem như là “boot schema”, ”hostfile”, hay “machinefile” ở
trên.
Ví dụ
# My boot schema
node1.cluster.example.com
node2.cluster.example.com
node3.cluster.example.com cpu=2
node4.cluster.example.com cpu=2
LAM cung cấp một số dòng lệnh để khởi tạo hệ LAM như sau
Dòng lệnh lamboot
Dòng lệnh lamboot được sử dụng để khởi chạy môi trường LAM.
Cho mỗi máy được liệt kê trong lược đồ khởi động, những điều
kiện sau đây phải được thoả mãn để khởi động môi trường LAM
đúng:
Mạng máy tính phải thông
Người dùng (user) có thể thực thi trên dòng lệnh mỗi máy
mà không cần password
Những tập tin thực thi LAM phải đựơc định vị trên máy
đó
Người dùng (user) phải có thể được viết trên thư mục
phiên làm việc LAM (thường là /tmp)
Những đọan mã khởi động của shell cấm in bất cứ thứ gì
lỗi chuẫn
Dòng lệnh lamnodes
Một cách dễ nhất để xem xét có bao nhiêu nút và CPUs trên hệ
thống LAM hiện thời là sử dụng lệnh lamnodes. Ví dụ dòng lệnh
lamnodes sẽ cho ra kết quả như sau :
shell$ lamnodes
Trang 71
n0 node1.cluster.example.com:1:origin,this node
n1 node2.cluster.example.com:1:
n2 node3.cluster.example.com:2:
n3 node4.cluster.example.com:2:
Trong ví dụ trên có tổng cộng 6 CPU sẵn dùng cho việc chạy
những xử lý .
• Biên dịch chương trình
Không cần thiết phải khởi tạo môi trường LAM/MPI .
Việc biên dịch chương trình MPI có thể là một xử lý phức tạp :
Cùng những trình biên dịch nên được sử dụng để biên dịch /liên
kết những chương trình MPI
Tuỳ thuộc vào việc cấu hình cài đặt cụ thể của LAM ,mà những
cờ -I, -Lvà –l v.v... có thể cần thiết trong khi biên dịch và liên kết
chương trình MPI
LAM/MPI cung cấp những trình biên dịch được xem như là vỏ
bọc bên ngoài để che dấu hết những sự phức tạp trong việc biên
dịch. Những trình biên dịch kiểu này là mpicc (cho chương trình
C), mpic++ (cho chương trình C++) và mpiff7 (cho chương trình
Fortran).Ví dụ
shell$ mpicc −g −c foo.c
shell$ mpicc −g −c bar.c
shell$ mpicc −g foo.o bar.o −o my mpi program
• Thực thi chương trình
Dòng lệnh mpirun
Dòng lệnh mpirun có nhiều tuỳ chọn khác nhau có thể được sử
dụng để điều khiển sự thực thi của một chương trình song song. Chúng em
chỉ đề cập một số tuỳ chọn đơn giản và dùng thường xuyên sau đây:
Cách đơn giản để khởi chạy tất cả chương trình ví dụ Hello với
tất cả các CPU được liệt kê trong tập tin lược đồ khởi động (boot schema)
là:
Trang 72
shell$ mpirun C hello
Tuỳ chọn C có nghĩa là sẽ chuyển giao một bản sao chép cho mỗi CPU
được liệt kê trong tập tin lược đồ khởi động.
Một phương pháp khác để thực thi chương trình song song là:
shell$mpirun N hello
Tuỳ chọn N khác với tuỳ chọn C, tuỳ chọn N có nghĩa là chuyển
giao một bản sao chép cho tất cả các nút trên hệ LAM. Vì thế số lượng nút
sẽ nhỏ hơn số lượng CPU. Điều này rất thích hợp với chương trình MPI đa
tiểu trình.
Cuối cùng , để chạy một chương trình MPI với số lượng xử lý cố định
(không quan tâm đến số lượng CPU hay số lượng nut trên hệ LAM)
shell$mpirun –np 4 hello
LAM sẽ lập biểu số lượng bản sao của chương trình sẽ chạy theo hình
thức vòng tròn trên mỗi nút với số lượng CPU được liệt kêt trong tập tin
lược đồ khởi động.
Chú ý rằng, bất kỳ số lượng xử lý có thể được sử dụng. Nếu số lượng xử
lý được sử dụng có lớn hơn số lượng CPU có trên hệ LAM, LAM sẽ
dùng cơ chế “wrap round" và bắt đầu lập biểu lần nữa với nút đầu tiên.
Dòng lệnh mpiexec
Chuẩn MPI-2 đòi hỏi sử dụng dòng liện mpiexec cho việc khởi động xử
lý MPI một cách linh động. Trên LAM/MPI, dòng lệnh này cũng tương
tự như dòng lệnh mpirun. Một vài tuỳ chọn của mpirun không có cho
mpiexec và ngược lại. Kết quả thì như nhau.
Dòng lệnh mpitask
Dòng lệnh mpitask cũng gần giống với dòng lện ps của Linux.
Nó cho biết trạng thái của chương trình MPI đang được thực thi trên hệ
LAM và hiển thị những thông tin chính về hàm MPI nào trên xử lý đang
được thi hành.
Dòng lệnh này có thể được thi hành trên bất kỳ nút nào của hệ LAM
Dòng lệnh lamclean :
Trang 73
Xoá hoàn toàn tất cả các chương trình đang chạy trên môi trường
LAM . Điều này có thể hữu ích nếu một công việc song song bị hỏng và
để lại trạng thái trên môi trường LAM. Lệnh này chạy không cần tham
số
shell$ lamclean
lamclean chỉ thiết yếu khi phát triển hay gỡ rối những ứng dụng MPI. Ví
dụ, những chương trình bị treo, những thông điệp lẩn quẩn v.v...Những
chương trình MPI đúng thực sự thì sẽ kết thúc mà không gây ra lỗi nào,
vì thế nó xoá tất cả các thông điệp của nó.
• Kết thúc LAM
Khi kết thúc chương trình MPI không dùng môi trường LAM nữa, ta
dùng dòng lệnh lamhalt
shell$lamhalt
Trong nhiều trường hợp, điều này hiệu quả khi tắt tất cả các xử lý MPI
đang chạy và tắt môi trường LAM. Tuy nhiên, trong một số điều kiện hiếm
gặp, lamhalt có thể không thực hiện được.Ví dụ, nếu một số nút trong môi
trường LAM bị hỏng, không truy xuất được (crash) trước khi chạy lệnh
lamhalt, lamhalt sẽ thiết lập thời đoạn timeout và sẽ không tất môi trường
LAM. Trong trường hợp này, chúng ta sẽ sử dụng lệnh lamwipe để bảo đảm
rằng môi trường LAM đã tắt hoàn toàn.
shell$lamwipe –v hostfile
3.3.3.4. Gỡ rối chương trình song song
Đặt tên những đối tượng MPI :
LAM/MPI hỗ trợ những hàm MPI-2 như MPI<type>_SET_NAME và
MPI_<type>_GET_NAME, <type> có thể là COMM, WIN, hay TYPE. Những
hàm này nên được khuyến cáo sử dụng khi gỡ rối những ứng dụng MPI .
Lý do sử dụng các hàm này là cho phép LAM hiển thị chính xác về MPI
communicator, dạng dữ liệu v.v...
Trình gỡ rối song song TotalView
LAM/MPI không cần cấu hình hay được biên biên dịch một cách đặc
biệt để thêm trình gỡ rối TotalView với những xử lý MPI
Trang 74
Chúng ta có thể gắn TotalView với những xử lý MPI trực tiếp bằng dòng lệnh
mpirun/mpiexec với những cách thức sau đây :
Sử dụng tham số -tv khi chạy mpirun hay mpiexec
shell$mpirun -tv[..những tham số khác của mpirun]
Ví dụ:shell$ mpirun –tv C my_mpi_program arg1 arg2 arg3
Khởi chạy mpirun một cách trực tiếp trong trình gỡ rối TotalView (không
dùng được với mpiexec)
shell$ totalview mpirun –a[...mpirun arguments... ]
Ví dụ: shell$ totalview mpirun –a C my_mpi_program tham số 1 tham số 2
Chú ý rằng tham số -a sau mpirun. Điều này chứng tỏ TotalView có những
tham số theo sau “-a” thuộc về mpirun và không thuộc về TotalView
Total View hoặc là gắn với tất cả các tiến trình bên trong ngữ cảnh
MPI_COMM_WORLD (xem chi tiết về lập trình MPI phần communicator)
hay chỉ là một tập con của nó. Tất cả các quyền điều khiển này thuộc về
TotalView, không thuộc về LAM.
3.3.3.5. Quy trình cài đặt thực nghiệm
Qui trình cài đặt LAM do chúng em thực hiện, tuỳ theo yêu cầu và cấu
hình của mạng do người dùng cài đặt, nên có thể khác hoặc giống với những gì
chúng em làm, người dùng có thể tự tìm kiếm thêm thông tin trên các trang
Website liên quan đến việc cài đặt LAM.
Hệ điều hành chúng em sử dụng là Red Hat 10, đã cài đặt các thư viện
lập trình cho ngôn ngữ C , C++, Fortran v.v...
Cài đặt
Giải nén tập tin cần cài đặt
$gunzip –c lam-7.1.tar.gz
$tar xzt lam-7.1.tar
Cấu hình
Tuỳ theo mạng của bạn sử dụng giao thức trên mạng của Linux là rsh
hay ssh. Khi cấu hình, nên đưa các tham số tuỳ chọn vào lúc gõ lệnh để cấu
hình
Trang 75
$cd lam-7.1
Cài đặt Lam vào thư mục /usr/local
$./configure --prefix=/usr/local
Mặc đinh cấu hình đều sử dụng rsh trong giao thức truyền thông trên mạng, với
máy của chúng em sử dụng ssh
Nếu muốn dùng ssh ta gõ lệnh sau đây
$./configure --with-rsh=”ssh-x”
Xây dựng môi trường LAM
$make all install
$make DESDIR=/tmp/lam install
Thiết lập một số biến môi trường trong lam
LAMHOME=/tmp/lam/usr/local
Cần xem lại dòng lệnh lamboot thực hiện để tất cả các máy trên mạng
được dùng LAM mà không cần dùng password cho tất cả các máy.
Lần lượt cài đặt tất cả các máy trên mạng phần mềm LAM. Sau đó bắt đầu cấu
hình để được một mạng dùng để lập trình song song MPI
Tạo cùng user có cùng account và password trên tất cả các máy đã được cài đặt
LAM.
Không như các phần mềm cài đặt trên hệ điều hành Windows, phần
mềm cài đặt trên hệ điều hành Linux dễ phát sinh lỗi và cả phần mềm mã
nguồn mở như LAM. Nếu có gì lỗi người dùng có thể tham khảo thêm chi tiết
trên các website liên quan hay các diễn đàn.
Do chúng ta sử dụng môi trường LAM với chuẩn lập trình dùng là
truyền thông điệp. Như vậy.chuẩn lập trình truyền thông điệp hỗ trợ cho chúng
ta những đặc điểm gì. Chúng ta sẽ tìm hiểu kỹ trong các phần sau đây.
3.4. Những kỹ thuật nâng cao hỗ trợ lập trình
Trong khi các công cụ và mô hình lập trình này là cực kỳ hữu dụng
(bằng chứng là một trong số chúng đã được sử dụng rộng rãi trong thực tế), tuy
nhiên chúng vẫn còn đang được phát triển để nâng cao hiệu năng và tính linh
họat. Mặc dù chúng ta có thể xây dựng chi tiết các ứng dụng bằng cách sử dụng
Trang 76
các mô hình và dịch vụ phổ biến, cấp thấp, nhưng cũng phải hướng tới mục
tiêu thực hiện các công việc này sao cho dễ nhất có thể. Chúng ta sẽ đề cập đến
một số khả năng của sự hỗ trợ lập trình cấp cao.
3.4.1. Các kỹ thuật truyền thống
Trong khi các ứng dụng được sự hỗ trợ của mô hình chia sẽ bộ nhớ
không còn hiệu quả trong Grid, thì vẫn còn một số các kỹ thuật hỗ trợ truyền
thống khác có thể được áp dụng vào trong Grid.
• Đan xen tính toán với việc giao tiếp : Điều này đòi hỏi khi trao đổi
thông tin phải có một sự lưu ý để khi biết được khi nào thì các dữ
liệu biên có thể được trao đổi trong khi công việc tính toán vẫn được
thực hiện trên đường biên.
• Kết hợp thông tin : Việc trao đổi thông tin sẽ trở nên hiệu quả hơn
nếu ta kết hợp nhiều thông điệp nhỏ lại trước khi gửi.
• Nén : Vấn đề về băng thông và độ trễ sẽ được giải quyết phần nào
nếu ta áp dụng những phương pháp nén dữ liệu hiệu quả trong quá
trình trao đổi thông tin.
• Điều chỉnh giao thức : Các ứng dụng sẽ gia tăng hiệu năng giao tiếp
nếu bằng cách điều chỉnh lại các tham số của giao thức trao đổi
thông tin, như kích thước của gói TCP…
Vấn đề chính yếu ở đây là làm thế nào để áp dụng được các kỹ thuật trên
vào trong các công cụ và mô hình lập trình sao cho nó hoàn toàn trong suốt với
người dùng khi thực hiện trên các ứng dụng Grid.
3.4.2. Các kỹ thuật hướng dữ liệu
Bên cạnh các kỹ thuật nhằm cải thiện hiệu năng trong quá trình trao đổi
thông tin, các kỹ thuật được áp dụng ở trên cũng hướng tới việc để làm sao
thực thi hiệu quả hơn đoạn mã MPI. Vậy các mô hình bất đồng bộ và không
chặt chẽ hơn có thể hỗ trợ như thế nào cho các mô hình lập trình? Rõ ràng các
kỹ thuật hướng dữ liệu có thể giải quyết điều này. Workflow là một ví dụ của
mô hình này. Một ví dụ khác là lập trình theo dòng tin.
Trang 77
Lập trình theo dòng tin có thể được sử dụng nhằm quản lý truy cập đến
nơi lưu trữ các dữ liệu lớn và kết hợp việc xử lý với trao đổi thông tin theo cách
thức phân tán. Việc cùng chỉ định các bộ lọc và các dòng tin trong môi trường
Grid là cả một vấn đề quan trọng. Lập trình theo dòng tin có rất nhiều ngữ
nghĩa và thể hiện rộng lớn. Điều này có liên quan mật thiết đến khái niệm các
dịch vụ trao đổi thông tin cấp cao sẽ được thảo luận ở bên dưới. Các kỹ thuật
suy đoán và tối ưu
3.4.3. Các kỹ thuật suy đoán và tối ưu
Một phương pháp khác nhằm gia tăng bất đồng bộ và linh hoạt trong
quá trình thực thi là áp dụng các kỹ thuật suy đoán và tối ưu. Bằng cách hướng
sự tương tự vào sự mô phỏng các sự kiện rời rạc đã được tối ưu, tính toán có
tính suy đoán hay tối ưu là một cách làm giảm sự đồng bộ và các yêu cầu giao
tiếp bằng cách cho phép sự thực thi mang tính suy đoán giữa nhiều máy trạm
(host) với khả năng sẽ có một vài công việc được tính toán tối ưu sẽ phải bị loại
bỏ nếu nó không dư thừa và không tương thích. Mục tiêu là nhằm điều khiển
cấp độ tối ưu sao cho phát huy tối đa lợi ích của việc thực thi không chặt chẽ
trong khi làm giảm tối đa các tính toán gây lãng phí.
3.4.4. Các kỹ thuật phân tán
Vẫn còn một kỹ thuật khác là phân phối các xử lý lên dữ liệu. Khi đi sâu
tìm hiểu về Grid, ta thấy các kiến trúc tiềm ẩn phức tạp, các phương pháp ngôn
ngữ dữ liệu song song đồng bộ hóa rõ ràng là không thích hợp. Giả sử không
quan tâm đến các yêu cầu về tính đồng bộ hóa và trao đổi thông tin với nhau,
thì các kỹ thuật phân tán đạt được băng thông rất cao giữa dữ liệu cục bộ và xử
lý.
Bên cạnh Grid, các kỹ thuật cơ bản này đã được áp dụng trong nhiều
trường hợp khác. Mô hình macroserver sử dụng phương pháp được phân hoạch
tốt và hướng thông điệp, và tiếp tục được phát triển để hỗ trợ kỹ thuật PIM
(Process-in-memory) trong thiết kế kiến trúc HTMT (Hybrid Technology
Multithreaded Architecture).
Trang 78
Một phương pháp tương tự có thể được suy ra từ môi trường Grid,
nhưng ở một cấp độ hoàn toàn khác. Kiến trúc Grid Datafarm được thiết kế để
khai thác việc truy cập cục bộ bằng cách sắp xếp các chương trình trên toàn các
đĩa phân tán với quy mô lớn. Điều này nhằm gia tăng sự kết hợp chặt chẽ giữa
khả năng lưu trữ và tính toán. Grid Datafarm cũng cung cấp các hàm API nhập
xuất song song.
3.4.5. Nhập xuất hướng Grid
Trong khi các hệ thống nhập xuất chỉ tập trung vào việc di chuyển dữ
liệu, thì rõ ràng nó có ảnh hưởng rất lớn đến cách thức chương trình được viết.
Mặc dù các tập tin Grid Datafarm được phân bố trên các đĩa nhưng nó có thể
được mở, đọc, và ghi như là một tập tin duy nhất.
3.4.6. Các dịch vụ giao tiếp cấp cao
Các mô hình lập trình khả thi có thể phụ thuộc vào sự hỗ trợ của cơ sở
hạ tầng hiện có. Các dịch vụ trao đổi thông tin cấp cao là một phần của cơ sở
này. Khái niệm “các dịch vụ trao đổi thông tin cấp cao” ở đây có thể là bất cứ
ngữ nghĩa nào ngòai khả năng trao đổi một chiều đơn giản nhưng đáng tin cậy
từ điểm A đến điểm B, hay thậm chí là multicast dữ liệu. Vì thế bất cứ những
gì cấu tạo nên các dịch vụ này đều được định nghĩa khá rộng và được thúc đẩy
phát triển bởi nhiều yếu tố khác nhau
Trong tính toán lưới, nắm vững và sử dụng được các topo mạng sẽ càng
ngày càng quan trọng, bởi vì tất cả các hiệu năng của Grid sẽ bị chi phối phần
lớn bởi độ trễ của đường truyền, điều này có nghĩa là trong 5 đến 10 năm tới
hay hơn nữa, băng thông của mạng sẽ được mở rông hơn nhưng tương ứng sẽ
không ngắn hơn (do sự giới hạn của độ trễ). Để duy trì được hiệu năng, các
công cụ lập trình như MPI sẽ phải quan tâm hơn đến topo của mạng. Một ví dụ
của công cụ này là MagPIe. MagPIe hỗ trợ một cách trong suốt cho các cluster
trên mạng diện rộng bằng cách giới hạn tối đa sự truyền dữ liệu cho các thao
tác tổng hợp trên các đường truyền yếu. Các thao tác này thay vì chịu ảnh
Trang 79
hưởng bởi O(nlogn) thông điệp đi quan toàn bộ đường kính của mạng như
truớc, thì giờ đây nó chỉ là đường kính trung bình của mạng.
Một động cơ thúc đẩy khác cho các dịch vụ trao đổi thông tin cấp cao là
nhu cầu của các thuộc tính giao tiếp cơ bản khác nhau. Một nhóm multicast
truyền thống xây dựng một bản định tuyến thích ứng và được định hướng bởi
các topo mạng vật lý. Việc định tuyến dựa vào nội dung sẽ cho phép ứng dụng
điều khiển lịch trình trao đổi, định tuyến dựa trên các yêu cầu cơ bản của
chương trình bên trong một nhóm multicast đã cho, hơn là chỉ đơn thuần trao
đổi thông tin một-một. Tất nhiên thiết kế này đòi hỏi phải theo topo ở một dạng
nào đó.
Vì thế các dịch vụ trao đổi thông tin có thể được phân thành nhiều lọai.
Một trong số chúng chỉ thực sự hiệu quả khi kiến trúc có định hướng theo topo
mạng, trong khi những cái khác thì không có trong bất cứ trường hợp nào.
• Làm tăng ngữ nghĩa thông tin : Còn hơn là trao đổi cách thức định
tuyến cơ bản, và hơn nữa, hầu hết có thể làm tăng khả năng trao đổi
thông tin mà chỉ cần thêm vào một vài tính năng. Một vài cách phổ
biến như dùng cache, bộ lọc, nén, mã hóa, chất lượng dịch vụ,
chuyển mã dữ liệu hay các chức năng được người dùng định nghĩa.
• Các thao tác tổng hơp : Các ứng dụng có thể yêu cầu các thao tác
đồng bộ hóa, về cơ bản chúng thường thực hiện cùng với một topo
thông tin theo thao tác một-một. Để đạt được hiệu năng trong mội
trường mạng diện rộng, việc kết gán các thao tác với các topo được
xác định bởi mạng vật lý hay ảo là một điều rất quan trọng.
• Định tuyến dựa vào nội dung hay chính sách : bằng cách cho phép
các ứng dụng quyết định việc định tuyến dựa vào các trường do ứng
dụng định nghĩa, sẽ tạo ra các tính năng như công bố hay đăng ký
vào các dịch vụ sự kiện. việc định tuyến dựa vào chính sách cũng là
một phương án khả thi khác. Ví dụ như là phải đáp ứng được các yêu
cầu của chất lượng dịch vụ (QoS) và các mô hình bảo toàn thông
Trang 80
điệp trong đó phải áp dụng chính sách trên trật tự đến của thông điệp
qua tập hợp các máy trạm cuối.
• Phạm vi trao đổi thông tin : Một vài dịch vụ có thể tốn chi phí rất
cao để thực hiện, đặc biệt trên phạm vi lớn. Ví thế nếu một ứng dụng
có thể tự định nghĩa phạm vi cho dịch vụ thì có thể sẽ giảm thiểu tối
đa vấn đề, từ đó làm cho tăng tính khả thi trong việc triển khai dịch
vụ. Phạm vi trao đổi thông tin có thể được kết hợp với một topo
được xác định để có thể quản lý nhiều phạm vi cho cùng hay các ứng
dụng riêng rẽ.
3.4.7. Bảo mật
Các ứng dụng có thể được yêu cầu chứng thực, cấp phép, kiểm tra tính
toàn vẹn và tính riêng tư. Trong ngữ cảnh của mô hình lập trình, điều này có
thể đem lại sự phân nhánh thêm. Về cơ bản, bảo mật một-một có thể được thực
hiện bằng cách tích hợp các phương pháp bào mật và cách thức lập trình. Một
ví dụ khác là sự kết hợp của SOAP với GSI. Tuy nhiên, trong ngữ cảnh lớn
những lời gọi hàm như RMI hay RPC có thể tồn tại trong một cây lời gọi (call
tree). Hỗ trợ bảo mật qua cây lời gọi đòi hỏi khái niệm delegation of trust.
Ký tên và chứng nhận các giấy phép trên RPC cũng phải được thực hiện
sao cho cân bằng với số lượng công việc hiện có. Sự quá tải do bảo mật có thể
được quản lý bằng cách thiết lập các domain bảo mật và được ủy nhiệm. Các
giấy phép sẽ được phân phối cho các RPC trong domain. Các domain được ủy
nhiệm có thể được dùng để giới hạn các quá tải về bảo mật trên từng RPC.
3.4.8. Dung lỗi
Tính dung lỗi và tin cậy trong các công cụ và mô hình lập trình lưới
phần lớn vẫn còn cần được tiếp tục ngiên cứu. Phạm vi cụ thể của một ứng
dụng nào đó thì có tính dung lỗi cao hơn so với các phạm vi khác. Tuy nhiên
vấn đề là ở chỗ làm thế nào để cho các mô hình và công cụ tính toán lưới trở
nên đáng tin cậy và ít lỗi hơn. Rõ ràng là có tồn tại sự khác biệt giữa hai tính
Trang 81
này trong ứng dụng và trong các mô hình/công cụ lập trình lưới và cũng là đối
với chính bản thân cơ sở hạ tầng Grid.
Một sự khác biệt xa hơn có thể xảy ra giữa khả năng phát hiện lỗi, thông
bào lỗi và phục hồi lỗi. Trong môi trường Grid phân tán, việc quan trọng là chỉ
cần nhận ra khi nào thì có lỗi xuất hiện. Việc truyền các thông báo đó cho các
site khác liên quan cũng quan trọng không kém. Cuối cùng là các site này phải
có khả năng phục hồi hay làm giảm các ảnh hưởng của lỗi.
Các khả năng này yêu cầu là các mô hình sự kiện phải được tích hợp
vào trong các mô hình và công cụ lập trình lưới. Các mô hình sự kiện được yêu
cầu cho mọi khía cạnh của tính tóan lưới, như là các bộ phận giám sát hiệu
năng. Vì thế việc triển khai các cách thức sự kiện lưới để chúng trở nên sẵn
sàng là một điều cần thiết. Cách sử dụng các phương pháp như vậy sẽ là yếu tố
cốt lõi cho các mô hình tính toán đáng tin và dung lỗi.
Một thí dụ cho vấn đề trên, hãy xem phương pháp Grid RPC. Về cơ bản
một RPC có một lời gọi và trả về trong cây lời gọi, nhưng cũng có thể có hủy
và từ chối. Trong một chuỗi RPC đồng bộ, phải theo hủy và từ chối theo một
đường tuyến tính. Tuy nhiên trong nhiều RPC bất đồng bộ thì chúng có thể đi
theo nhiều nhánh. Từ chối cũng có thể thực hiện trên nhiều nhánh khác.
Vì thế cách thức Grid RPC rõ ràng là cần một dịch vụ sự kiện để quản lý
các thao tác hùy và từ chối. Điều này rất quan trọng trong việc thiết kế và cài
đặt phương pháp RPC mang tính dung lỗi, nghĩa là phương pháp mà trong đó
bất cứ các thao tác bất thường nào cũng đều được xác định trong một khoảng
thời gian nào đó và được cảnh báo, nhớ đó mà các dịch vụ GPC có thể xóa các
trạng thái không còn thích hợp.
Trong khi trường hợp đơn giản nhất (mà cũng có thể là phổ biến nhất)
của việc hủy sẽ liên quan đến RPC được thực hiện trên một sự kiện phân phối
đơn theo một-một, thì việc hủy toàn bộ RPC là điều hữu ích. Trong trường hợp
này, RPC có thể được xem như là một nhóm tiến trình. Một nhóm tiến trình
như vậy có thể bao gồm một nhánh hoạt động của cây lời gọi, một cây lời gọi
song song với một nút gốc, hay là một hay nhiều nhánh của cây lời gọi không
chứa nút gốc.
Trang 82
Việc hủy trên toàn bộ nhóm tiến trình có thể được thực hiện theo các sư
kiện một-một. Tuy nhiên sự kiện thông báo một-nhiều hay một vài-nhiều sẽ
làm cho toàn bộ nhóm bị hủy nhanh hơn. Những sự kiện thông báo nhóm như
vậy có thể được thực hiện bởi các thành viên trong nhóm hay bởi giao diện
publish/subcribe nhờ đó mà các máy chủ RPC từ xa có thể đăng ký vào để hủy
các sự kiện của các nhóm tiến trình trên các ROC khác.
3.4.9. Các siêu mô hình và hệ thống thời gian thực hướng Grid
Còn một vấn đề khác trong các mô hình lập trình lưới là khái niệm về
các siêu mô hình và ứng dụng của nó trong hệ thống thời gian thực hướng Grid.
Bất kể người ta đã triển khai Grid như thế nào, thì chúng cũng sẽ bao gồm các
thành phần và dịch vụ cố định hay tùy biến. Một vài trong số chúng sẽ được sử
dụng rộng rãi và trở nên phổ biến. Vì thế, nhiều ứng dụng sẽ được xây dựng
toàn bộ hay một phần bằng cách kết hợp các thành phần và dịch vụ khác.
Làm sao việc kết hợp như vậy có thể được thực hiện một cách tự động
mà vẫn đạt được hiệu năng cao bên cạnh các yếu tố như bảo mật và dung lỗi?
Điều này chỉ có thể được thực hiện khi có sự xuất hiện của một khái niệm là
siêu mô hình, cho phép định nghĩa các thuộc tính và tính chất của các thành
phần. Các siêu mô hình này có thể được thực hiện bằng tay hay một cách tự
động
Chính vì thế các trình biên dịch và các công cụ kết hợp có thể chịu trách
nhiệm tạo ra các siêu mô hình và sử dụng chúng để nhận ra và thúc đẩy các sự
kết hợp hợp lý khác. Khái niệm ‘hợp lý’ ở đây không chỉ có nghĩa đơn thuần là
các thông số giao diện phải tương thích, mà còn có nghĩa là giữ lại những tính
chất hiệu năng, các thuộc tính bảo mật hay kháng lỗi. Về cơ bản của một
chương trình cấp độ cao, một ‘trình biên dịch’ có thể ánh xạ các ngữ nghĩa ở
cấp độ cao hơn vào các thành phần và dịch vụ thấp hơn. Điều này có khả năng
dẫn đến một khái niệm mới là ‘trình biên dịch hướng Grid’, mà nó cũng sẽ
không theo ngữ nghĩa truyền thống là các chỉ thị máy mà hơn nữa là tập hợp
các dịch vụ hiện có phổ biến.
Trang 83
Dự án Phần mềm phát triển ứng dụng Grid (Grid Application
Development Software - GrADS) đã đi tiên phong trong lĩnh vực này.
3.5. Tóm tắt
Chúng ta vừa xem qua các mô hình lập trình cho các môi trường tính
toán lưới. Cũng như trong các lĩnh vực cơ bản khác, một mô hình tính toán lưới
thành công cũng phải bao gồm nhiều khía cạnh. Những điều này bao gồm khả
năng mang chuyển, tính cộng tác, tính thích ứng và khả năng phát hiện, bảo
mật, dung lỗi trong quá trình duy trì hiệu năng. Chúng ta cũng đã chỉ ra một số
kỹ năng quan trọng như các kỹ thuật lập trình tối ưu và hướng dữ liệu, các dịch
vụ nhập xuất và trao đổi thông tin cấp cao và cuối cùng là các mô hình lai.
Tuy nhiên bất kể các điều này, các mô hình và công cụ lập trình sẽ được
phát triển phần lớn dựa vào mô hình và công cụ nào được xem là chiếm ưu thế.
Những cải tiến cho các mô hình này sẽ khó có thể làm thỏa mãn tất cả nhưng
nó sẽ có tiềm năng phát triển rộng lớn trong cộng đồng người dùng. Tuy nhiên
vẫn còn một số khác biệt giữa các khả năng mà cơ sở hạ tầng và các công cụ,
mô hình lập trình được xây dựng bên trên nó.
Với sự quan tâm đến cơ sở hạ tầng chung, động cơ thương mại to lớn
thúc đẩy thúc đẩy sự phát triển của các dịch vụ web cho thấy việc tạo điều kiện
cho sự phát triển của các tính năng này cho tính toán khoa học và công nghệ.
Chính vì thế, để đạt được các lý do thực tiễn này, chúng ta sẽ thấy khả năng
phát triển tiếp theo của kiến trúc dịch vụ mở (Open Grid Services Architecture)
.
Với sự quan tâm về các công cụ và mô hình lập trình, và cùng với cùng
các lý do thực tế như vậy, chúng ta cũng sẽ tiếp tục thấy sự phát triển của MPI.
MPI là một chuẩn được thiết lập dựa vào người dùng. Các cải tiến đã được cải
thiện ở trên có thể đem lại một số thay đổi nhỏ trong các hàm API của MPI.
Tuy hiên những mô hình và công cụ khác cũng sẽ có một sự phát triển
vượt bậc. Một nền tảng với sự hỗ trợ rộng rãi của các dịch vụ được xây dựng
trên các dịch vụ cơ bản của Grid, như là Cactus và XCAT, sẽ tích hợp các khả
năng mà chúng ta vừa thảo luận. Tuy nhiên đối với các ứng dụng khác, một
Trang 84
kiến trúc lập trình hướng Grid như GridRPC là hoàn toàn đủ cho các thiết kế và
thực hiện.
Cuối cùng chúng ta sẽ thảo luận về phong cách lập trình. Sự phát triển
trong các nền tảng tính toán hiện hành, từ các máy đơn đến các máy song song
rồi đến Grid, sẽ thúc đẩy cho một sự phát triển tương ứng về cách thức lập trình
như thế nào để giải quyết các vấn đề tính toán. Theo tự nhiên thì các lập trình
viên sẽ phỏng các đoạn mã nguồn và phong các lập trình sao cho phù hợp với
cơ sở hạ tầng hiện có. Họ sẽ cố gắng làm cho các dòng lệnh càng thích nghi
hơn. Kiến trúc để giải quyết vấn đề sẽ được hình thành theo cách sao cho nó
càng thích nghi hơn với môi trường Grid.
Điều này đồng thời lại làm nảy sinh ra một vấn đề khác. Bên cạnh tính
nặng động to lớn mà tính toán lưới đem lại cho các tổ chức ảo, vậy nó có tồn
tại những giới hạn gì cho tính toán khoa học? Liệu các tính toán khoa học sẽ bị
giới hạn bởi kích thước các máy “khung đơn” như máy ASCI, và HTMT? Hay
khi giải pháp của các vấn đề cho khoa học và công nghệ, và sự kết hợp với các
mô hình tính toán được làm cho thích hợp hoàn toàn với tính toán lưới thì có
thể giải quyết được các vấn đề lớn hay không? Chúng ta thấy là vẫn còn khá
nhiều việc để làm.
Trang 85
Chương 4. Mô hình lập trình truyền thông điệp - MPI Trong mô hình lập trình MPI, một phép tính toán bao gồm một hay
nhiều tiến trình, giao tiếp với nhau bằng cách gọi các thủ tục thư viện để trụyền
và gửi thông điệp cho các tiến trình khác. Trong khi thi hành hầu hết các
chương trình MPI, một tập hợp cố định các tiến trình được tạo lập khi khởi tạo
chương trình, và một tiến trình được tạo ra trên một bộ xử lý. Tuy nhiên các
tiến trình này có thể thực thi các chương trình khác nhau. Vì thế đôi khi mô
hình lập trình MPI được biết đến là đa chương trình đa dữ liệu (multiple
program multiple data - MPMD) để phân biệt với mô hình SPMD, mô hình mà
trong đó mỗi bộ xử sẽ thực thi cùng một chương trình.
Bởi vì số lượng các tiến trình trong chương trình MPI là cố định, cho
nên trong phần này chúng ta sẽ dựa trên cách này để thực hiện trao đổi dữ liệu
giữa chúng. Các tiến trình có thể thực hiện trao đổi thông tin một-một để gửi
dữ liệu từ tiến trình này sang tiến trình khác. Một nhóm các tiến trình có thể
thực hiện các thao tác kết hợp để thực hiện các thao tác chung và phổ biến như
là phép cộng hay broadcast. MPI có khả năng dò các thông điệp có hỗ trợ
truyền thông bất đồng bộ.
Các thuật toán chỉ tạo ra một tác vụ trên một bộ xử lý có thể áp dụng
trực tiếp các thủ tục trao đổi kết hợp hay một-một nhằm đáp ứng các yêu cầu
truyền thông. Trong khi đó các thuật toán tạo tác vụ động hay dựa trên sự thực
thi đồng thời của nhiều tác vụ trên cùng một bộ xử lý, thì cần phải điều chỉnh
lại cho thích hợp với mô hình MPI.
Chương trình MPI có thể chạy trên các hệ thống phân tán hay còn gọi là
distributed-memory hoặc máy tính với nhiều bộ xử lý multicomputers, hoặc
grid computing v.v...
Trang 86
Hình 4-1 : Các tiến trình tạo lập trên mô hình lập trình MPI
Với các hệ thống mạng không phải là phân tán, thì mô hình MPI cho
ứng dụng có thể được thực thi với một sự giúp đỡ của một dịch vụ, chẳng hạn
như phần mềm Lam 7.1.1 có thể kết nối tất cả các máy tính trên cùng một
mạng sử dụng hệ điều hành Linux dùng để thực thi chương trình viết bằng MPI
trên hệ thống mạng đó. Lúc này người dùng chỉ nhìn chương trình viết cho
nhiều bộ xử lý trên mạng như viết trên một máy có nhiều bộ xử lý
4.1. Các khái niệm cơ bản
Process: (hay còn gọi là tiến trình hoặc xử lý): với kiểu lập trình trên
một máy có một bộ xử lý thì process được coi như là một tiến trình trong một
chương trình có không gian điạ chỉ riêng do hệ điều hành cung cấp. Với
phương pháp lập trình song song để giải quyết các bài toán phức tạp thì process
được xem như là một xử lý đang chạy một một máy và chương trình MPI phân
bố các xử lý này trên hệ thống mạng lên các máy tính với địa chỉ IP khác nhau.
Send/Receive: vì các chương trình sử dụng phương pháp lập trình
Message Passing không chia sẻ vùng nhớ chung, hay biến cục bộ, mà tất cả các
dạng dữ liệu đều phải giao tiếp thông qua truyền thông. Do đó MPI định nghĩa
Trang 87
Send /Receive là hai cơ chế gửi và nhận thông điệp giữa các xử lý trên các máy
khác nhau. Một xử lý muốn gửi dữ liệu đến xử lý khác thì phải dùng thủ tục
Send và xử lý nhận phải dùng thủ tục Receive để đón bắt dữ liệu
Đồng bộ và bất đồng bộ (Synchoronous/Asynchronous ) là hai cơ chế
đặc biệt liên quan đến việc lập trình song song. Giống như việc lập trình dùng
tiểu trình trên Windows hay trên Linux, việc đồng bộ hóa được thực hiện trên
các dữ liệu chung (biến cục bộ) thì phải dùng các đối tượng do hệ điều hành
cung cấp như Mutex, Monitor v.v... Còn với MPI do không chia sẻ vùng nhớ
chung nên việc đồng bộ ở đây chỉ đề cập đến hình thức dữ liệu truyền nhận.
Nên chương trình MPI thuộc dạng không đồng bộ vì mỗi xử lý trên các máy
khác nhau chỉ thực hiện xử lý của mình mà không quan tâm đến dữ liệu của xử
lý trên máy khác. Vì thế sự đồng bộ đề cập là tất cả các dữ liệu đều được nhận
bởi các xử lý trên các máy hay giữa các xử lý có sự bắt tay nhau trong việc gửi
nhận thông tin.
Bộ đệm ứng dụng và bộ đệm hệ thống (Application Buffer /System
Buffer): Nếu muốn đạt được sự xử lý nhanh chóng giữa việc truyền thông dữ
liệu và xử lý dữ liệu thì MPI đưa ra thêm một khái niệm nữa là bộ đệm ứng
dụng. Bộ đệm hệ thống dùng để lưu trữ dữ liệu từ bộ đệm ứng dụng (hay còn
gọi là biến trong lập trình). Dữ liệu trong bộ đệm hệ thống dùng để truyền đi
đến các xử lý nhận hay nhận dữ liệu từ các xử lý khác.
Hình 4-2 : Cách thức truyền thông của các process
Blocking và non-blocking: Đây đặc điểm cần chú ý khác trên lập trình
song song. Blocking được xem là khoảng thời gian mà xử lý phải đợi để thực
Trang 88
hiện một xử lý con đang chạy ở dạng nền, trái ngược với nó là non-blocking có
nghĩa là không cần phải đợi. Khái niệm này giống như chúng ta viết các
chương trình dạng tuần tự với các chương trình dùng tiểu trình trên Windows
Hình 4-3 : Blocking và non-blocking
Group là một nhóm các xử lý.
Communicator được xem như vỏ bọc của Group dùng để quản lý các
Group và các xử lý bên trong Group.
Rank còn gọi là định danh của xử lý ,một khái niệm tương tự như định
danh của tiểu trình trên Window. Đồng thời nó còn hàm ý cả đặc tả địa chỉ máy
nếu thực thi chương trình trên hệ thống mạng. Rank có giá trị từ 0 đến n-1 với
n là số xử lý của chương trình MPI hay số node trên mạng do người thực thi
chương trình sử dụng để chạy chương trình MPI.
Hình 4-4 : Group, communicator và rank
Trang 89
4.2. Cấu trúc chương trình MPI
Các tập tin thư viện: liên quan đến các hàm các thủ tục, các kiểu dữ liệu.
Bao gồm các tập tin .h như mpi.h mpio.h và các tập tin khác. Người lập trình
chỉ cần dùng thư viện mpi.h là đủ.
Môi trường MPI: Tất cả các kiểu dữ liệu, các thủ tục, các giá trị defined
nếu muốn dùng nó, sau khi gọi các tập tin thư viện liên kết thì phải khởi tạo
môi trường sử dụng thì mới có thể dùng được các chức năng mà MPI cung cấp.
Các thủ tục, hàm MPI: sử dụng giống như các hàm trong C và cả các ngôn ngữ
khác như Fortran
Hình 4-5 : Cấu trúc của chương trình MPI
Thủ tục quản lý môi trường
+ Khởi tạo môi trường MPI :
MPI_Init(int argv,char***argc)
Hai tham số này nhận từ hai tham số của hàm main(int agrv,char**argc)
Hàm này phải được gọi đầu tiên trong chương trình và chỉ gọi mội lần duy nhất
+ Lấy số lượng các xử lý trong communicator
MPI_Comm_size(MPI_Comm com,int *size)
com là một kiểu dữ liệu do MPI định nghĩa để đặt tả thông tin về một
communicator. Chúng ta thường dùng MPI_COMM_WORLD để thay thế cho
giá trị này trong đoạn code sau hàm MPI_Init để lấy số lượng các xử lý do
người dùng nhập từ dòng lệnh để ứng dụng MPI xử lý.
+ Lấy ID của các xử lý
MPI_Comm_rank(MPI_Comm com,int *rank)
Trang 90
Thông tin nhập vào là Communicator bao bọc các xử lý, và trả về ID của xử lý
nào.
+ Thoát khỏi môi trường MPI
MPI_Finalize(): Thủ tục được gọi sau cùng để thoát khỏi môi trường thực thi
MPI. Nếu thiếu thủ tục này thì xử lý do MPI tạo ra coi như bị một lỗi và
chương trình sẽ không thực hiện được.
Còn một số các thủ tục liên quan đến Communicator và Group sẽ đề cập
trong phần Group và Commmunicator sau.
4.3. Trao đổi thông tin điểm-điểm
Kỹ thuật truyền thông cơ bản của MPI là sự chuyển giao dữ liệu giữa hai
xử lý, một bên gửi và một bên nhận, chúng ta gọi hình hình thức này là Point to
Point (điểm điểm). Hầu hết các cấu trúc xử lý của chuẩn MPI đều dựa trên
truyền thông Point to Point .
4.3.1. Các thông tin của thông điệp
Data : dữ liệu được truyền đi hay nhận về, là một kiểu con trỏ (void *)
trỏ đến vùng nhớ chứa dữ liệu. Đây coi như là biến sử dụng trong lập trình.
DataType : kiểu dữ liệu (đã định nghĩa )
Đối với các xử lý muốn gửi dữ liệu thì kiểu dữ liệu có thể là kiểu dữ liệu
bổ sung hoặc kiểu dữ liệu đã đươc định nghĩa.
Đối với các xử lý nhận thì kiểu dữ liệu chủ yếu vẫn là kiễu dữ liệu đã
được định nghĩa.
Count : Số lượng dữ liệu truyền đi. Ví dụ muốn truyền đi một mảng 4
phần tử kiểu nguyên, thì Count có giá trị bằng 4, DataType=MPI_INT
Source : Xử lý nơi gửi thông điệp, dành cho những tiến trình nhận thông
điệp. MPI cung cấp một giá trị là MPI_ANY_SOURCE để các tiến trình có thể
đón bắt được các thông điệp từ bất kỳ tiến trình nào gửi thông điệp trên một
communicator.
Destination : Xử lý nơi nhận thông điệp, dành cho những tiến trình gửi
thông điệp.
Trang 91
Tag : Định danh của thông điệp (có thể so sánh trong lập trình mạng là
socket của ứng dụng mạng). Các tiến trình gửi và nhận thông điệp lấy chính
xác dữ liệu thông qua định danh Tag này. MPI cung cấp một giá trị là
MPI_ANY_TAG để cho các tiến trình nhận thông điệp, nhận đựơc bất kỳ dữ
liệu nào.
4.3.2. Các hình thức truyền thông
MPI cung cấp các hình thức truyền thông khác nhau dựa trên điều kiện
hoàn thành của việc gửi và nhận thông điệp giữa các tiến trình với nhau. MPI
đưa ra 4 hình thức truyền thông sau đây:
• Đồng bộ (Synchoronous send)
Khi xử lý trên một máy gửi thông điệp đến xử lý của một máy khác trên
mạng thì xử lý nhận của máy đó sau khi nhận được thông tin thì phải gửi trả kết
quả trở về cho xử lý đã gửi thông tin. Do đó xử lý gửi thông tin biết được thông
điệp do mình truyền đi đã được nhận.
• Bộ đệm (Buffer Send) Xử lý nơi gửi thông điệp đến một xử lý khác, việc hoàn thành khi thông
điệp đã được chép sang một bộ nhớ phụ (dùng bộ đệm thay thế). Người dùng
có thể bảo đảm rằng một số lượng lớn không gian bộ đệm sẵn dùng.
• Chuẩn (Standard Send) Sự hoàn thành của việc gửi thông điệp không thật sự cần thiết khi một
xử lý nhận thông điệp đã bắt đầu.
• Sẵn sàng (Ready Send) Xử lý (nơi gửi thông điệp) phải biết chắc chắn đã có một xử lý khác
đang đợi thông điệp. Đây là hình thức xử lý gửi nhận thông điệp rất chắc chắn.
Nếu không việc gửi thông điệp sẽ bị lỗi trong khi thực thi chương trình
Trang 92
4.3.3. Giao tiếp blocking
Hình 4-6 : Giao tiếp blocking
4.3.3.1. Blocking Send
MPI_Send(buf, count, datatype, dest, tag, comm)
IN :
buf : địa chỉ đầu của bộ đệm dữ liệu cần gửi count : số lượng mục cần gửi
datatype : kiểu dữ liệu
dest : bộ xử lý đích
tag : thẻ thông điệp
comm : communicator
MPI_Ssend(void *buf,int count,MPI_Datatype datatype,int dest,int
tag,MPI_Comm comm)
Đồng bộ blocking send: Gửi một thông điệp và chờ cho đến khi bộ đệm
ứng dụng trong tác vụ gửi được giải phóng và xử lý đích đã bắt đầu nhận thông
điệp.
MPI_Bsend(void *buf,int count,MPI_Datatype datatype,int dest,int
tag,MPI_Comm comm)
Trang 93
Khóa bộ đệm gửi: Sao chép bộ đệm ứng dụng vào bộ đệm gửi do người
dùng định nghĩa để dùng cho lần truyền thông sau. Sau đó sự truyền thông dựa
trên bộ đệm này. Khi dùng phương thức gửi thông điệp dạng này cần phải bổ
sung thêm hai hàm sau đây:
MPI_Buffer_attach(void *buffer,int size)
Sử dụng cho lập trình viên để định phần hay định phần lại không gian bộ
đệm thông điệp để được sử dụng cho MPI_Bsend. Tham số kích thước size
được đặt tả ở dạng những byte dữ liệu, không một số lượng thành phần dữ liệu.
Chỉ có một bộ đệm có thể được gán cho một xử lý vào cùng một thời điểm.
MPI_Rsend(void *buff,int count,MPI_Datatype datatype,int
dest,int tag,MPI_Comm comm)
Chỉ nên sử dụng hàm này chỉ khi lập trình viên chắc chắn rằng một
receive phù hợp với hàm gửi đã được đưa lên xử lý.
MPI_Sendrecv(void *sendbuf,int sendcount,MPI_Datatype
sendtype,int dest, int sendtag,void recvbuf,int
recvcount,MPI_Datatype recvtype,int source,int
recvtag,MPI_Comm comm,MPI_Status *status)
Gửi một thông điệp và đưa lên một trình nhận thông điệp (receive) trước
khi khóa lại. Sẽ khóa cho đến khi bộ đệm ứng dụng dùng để gửi được giải
phóng cho sử dụng lại và cho đến khi bộ đệm ứng dụng dùng để nhận thông
điệp chứa thông điệp đã nhận.
4.3.3.2. Blocking Receive
MPI_Receive(void *buf,int count,MPI_Datatype datatype,int
source,int tag,MPI_Comm comm,MPI_Status status)
OUT :
buf : vùng đệm dữ liệu nhận được
status : các thông tin liên quan đến việc nhận và gửi. (ví dụ như
tiến trình nào gửi và thông điệp có định dạng gì)
IN :
count : số lượng dữ liệu nhận được
datatype : kiểu dữ liêu của của vùng đệm
Trang 94
source : rank của xử lý
tag : thẻ thông điệp
comm : communicator mà xử lý thuộc về
4.3.3.3. Ngữ nghĩa của blocking communication
Bộ đệm và an toàn dữ liệu
Hàm nhận (MPI_Recv) có thể khởi động mà không cần một hàm gửi
(MPI_Send ) khớp với nó được đưa ra, nó chỉ trả về sau khi một bộ đệm nhận
đã nhận được thông điệp mới. Hàm nhận có thể hoàn thành trước một hàm gửi
tương ứng và tất nhiên khi đó hàm gửi đã khởi chạy rồi.
Tương tự như vậy, hàm gửi cũng có thể được khởi chạy dù có hay
không có một hàm nhận đã được gửi lên. Nó sẽ không trả về giá trị chừng nào
mà dữ liệu thông điệp và được lưu trữ một cách an toàn để người gửi giải
phóng truy xuất và ghi chồng lên bộ đệm gửi sau khi tất cả dữ liệu của bộ đệm
gửi đã chuyển sang bộ đệm hệ thống. Lời gọi gửi cũng là dạng non_local, dạng
này thông điệp có thể được sao chép trực tiếp vào bộ đệm nhận tương ứng.
Trong trường hợp này hàm send sẽ không hoàn thành trừ khi hàm nhận tương
ứng xảy ra và vì thế nếu xử lý nhận là một tiểu trình thì nó sẽ bị khóa trong thời
điểm này. Trong trường hợp ngược lại nó có thể được sao chép vào một bộ
đệm hệ thống tạm thời và lời gọi gửi có thể trả về trước lời gọi hàm nhận, cho
phép xử lý đơn tiểu trình tiếp tục tính toán. Sự thực hiện MPI có thể có 2 chọn
lựa này. Nó có thể ngăn cản người gửi hay nó có thể đưa dữ liệu vào bộ đệm.
Thông điệp được đưa vào bộ đệm bằng cách phân tách thao tác gửi và
nhận. Một blocking send có thể hoàn thành ngay sau khi thông điệp được đưa
vào bộ đệm, chỉ khi không có hàm nhận tương ứng thực thi, điều này yêu cầu
việc sao chép bộ nhớ.
Thứ tự thông điệp thực hiện như sau :
Thông điệp sẽ được gửi vào một hàng đợi và những thao tác Receive
cũng được đưa vào hàng đợi. Mỗi thông điệp vào đến sẽ tương ứng với tiến
trình nhận tương ứng. Có thể minh họa theo hình vẽ sau đây
Trang 95
Hình 4-7 : Thứ tự các xử lý
Xử lý 0 sẽ gửi hai thông điệp đến xử lý 1, xử lý 2 sẽ gửi 3 thông điệp
đến xử lý 1. Thứ tự nhận thông điệp của xử lý 1 là sau khi nhận thông điệp thứ
1 của xử lý 0 và thông điệp 1 của xử lý 2 thì sẽ nhận thông điệp 2 của xử lý 2
trước đến thông điệp thứ 3 của xử lý 2 và cuối cùng là thông điệp của xử lý 1
Thứ tự sẽ không biết trước được. Đây cũng là đặc điểm của chương trình viết
bằng MPI.
Vì vậy, khi môt tiến trình gửi hai thông điệp đến cùng một tiến trình
đích và cả hai đều cùng một trình nhận thông điệp, thì trình nhận thông điệp sẽ
không nhận thông điệp thứ hai nếu thông điệp thứ nhất ở trạng thái chờ. Và nếu
một trình nhận gửi lên hai hàm recv và cả hai đều tương ứng cùng thông điệp
thì xử lý nhận thông điệp thứ hai sẽ không thực hoàn thành nếu xử lý thông
điệp thứ nhất vẫn chưa xong.
Hình 4-8 : Cách thức xử lý tiến trình
Trang 96
4.3.4. Giao tiếp non-blocking
Hình 4-9 : Giao tiếp non-blocking
Phân loại theo các hình thức truyền thông thì non-blocking cũng có một
số thủ tục tương tự như các thủ tục blocking và có thêm các tham số trong thủ
tục như sau nhằm để quản lý các tiến trình gửi
Request object : Kiểu dữ liệu MPI_Request
Ý nghĩa :
Nonblocking communication sử dụng đối tượng request để yêu cầu
đối tượng nhận diện những họat động truyền thông và liên kết với những thao
tác xem xét sự hoàn thành của tác vụ. Đối tượng request được định rõ vị trí
trong bộ nhớ hệ thống MPI. Người dùng không biết đến cấu trúc của những đối
tượng này. Chương trình ứng dụng chỉ vận dụng thẻ điều khiển (handle) đối
tượng. Hệ thống có thể dùng đối tượng request này để xác định một số thuộc
tính khác của những thao tác truyền thông, chẳng hạn như bộ đệm truyền thông
liên quan đến nó, hay để lưu trữ thông tin về những về trạng thái chưa được
giải quyết của các họat động truyền thông (gửi, nhận).
4.3.3.1. Non-Blocking Send
Trang 97
Tương tự các Blocking Send hay Receive của blocking communication,
nhưng tên hàm còn có thêm chữ “I” phía trước.
MPI_Isend(void* buf, int count, MPI_Datatype datatype, int dest, int
tag, MPI_Comm comm, MPI_Request *request)
MPI_Issend (void *buf,int count,MPI_Datatype datatype,int dest,int
tag,MPI_Comm comm,MPI_Request *request)
Giống như MPI_Isend(), ngoại trừ hàm MPI_Wait() hoặc MPI_Test chỉ
ra rằng khi nào thì xử lý đích đã nhận được thông điệp.
MPI_Ibsend (void *buf,int count,MPI_Datatype datatype,int dest,int
tag,MPI_Comm comm,MPI_Request *request)
Giống như MPI_Bsend() ngoại trừ MPI_Wait() hay MPI_Test chỉ ra
rằng xử lý đích đã nhận được thông điệp hay chưa. Hàm này phải được sử dụng
với hàm MPI_Buffer_attach.
MPI_Irsend(void *buf,int count,MPI_Datatype datatype,int dest, int
tag,MPI_Comm comm,MPI_Request *request)
Giống như MPI_Rsend() ngoại trừ MPI_Wait() hay MPI_Test() chỉ ra
rằng khi nào thì xử lý chính nhận thông điệp. Chỉ nên sử dụng nếu lập trình
viên chắc chắn rằng có một trình nhận thông điệp thích hợp ở xử lý đích đã
được đưa lên.
4.3.3.2. Non-Blocking Receive
MPI_Irecv(void* buf, int count, MPI_Datatype datatype, int source, int
tag, MPI_Comm comm, MPI_Request *request)
thêm vào đối tượng có kiểu dữ liệu MPI_Request dùng để trả về thẻ điều khiển.
Và thẻ này dùng trong các trường hợp chờ trạng thái hoàn thành của các
Posting Operations, quản lý tiến trình nhận và gửi thông điệp.
Lưu ý rằng bộ đệm gửi và bộ đệm nhận sẽ không được truy xuất khi
các Posting Operations đã được thực hiện cho đến khi nó hoàn thành. Nếu truy
xuất bộ đệm ứng dụng trong khi các thao tác gửi và nhận chưa hoàn thành thì
sẽ gây ra dữ liệu bị sai.
Chằng hạn, khi hệ thống bắt đầu sao chép dữ liệu ra khỏi bộ đệm gửi
thì không được truy xuất những phần của bộ đệm này cho đến khi nhận giá trị
Trang 98
trả về của hệ thống thực thi gửi thông điệp, tương tự truy xuất cho thao tác
nhận.
4.3.3.3. Kiểm tra sự hoàn thành của các tiến trình nhận
Bởi vì các hàm trong Posting Operation không được biết trước sự
hoàn thành khi được khởi chạy. Nên MPI cung cấp chức năng chờ cho đến khi
thao tác Send và Receive đã hoàn thành. Nếu thao tác non blocking Send và
Receive có thêm các thao tác chờ sự hoàn thành thì giống như hàm blocking.
Có thể hình dung như thế này
MPI_Isend()+MPI_Wait() = = MPI_Send()
MPI_Irecv()+MPI_Wait() = = MPI_Recv()
Phân loại kiểu kiểm sự hoàn thành trong truyền thông
Blocking
Kiểm tra sự hoàn thành của các tiến trình gửi hoặc nhận và dùng lại
các thông tin liên quan đến các đối tượng này, chủ yếu là vùng nhớ ứng dụng
dùng để gửi dữ liệu.Các hàm do MPI cung cấp có tên Wait.
Non-blocking :
Chỉ kiểm tra xem đã hoàn thành 1 tác vụ hay chưa, hàm này trả về
ngay tại thời điểm đó. Và nếu tác vụ đã hoàn thành thì trả về thêm các thông tin
liên quan đến sự hoàn thành đó, ngược lại trả về một giá trị không định nghĩa.
Các hàm này mang tên Test
MPI_Wait(MPI_Request *request,MPI_Status *status)
Chờ cho đến khi tiến trình nhận thông điệp nhận được thông điệp hoàn
toàn, thông qua thẻ điều khiển request liên quan đến tiến trình nhận thông điệp.
Và biến status sẽ nhận được trạng thái của tiến trình nhận như định danh thông
điệp v.v...
MPI_Test (MPI_Request *request,int *flag,MPI_Status *status)
Gọi hàm MPI_Test, flag trả về bằng true nếu thao tác gửi hoặc nhận
được xác định bằng đối tượng request đã hoàn thành. Trong trường hợp này,
đối tượng trạng thái status được thiết lập nội dung thông tin trên thao tác đã
hoàn thành và đối tượng request sẽ được gán giá trị MPI_REQUEST_NULL.
Trang 99
Ngược lại, flag trả về bằng false. Trong trường hợp này, giá trị của đối tượng
trạng thái status là không xác định.
Cả hàm MPI_Wait và MPI_Test, thông tin trả về thao tác hoàn thành
đều dựa trên thông tin đối tượng trạng thái status. Nội dung của đối tượng trạng
thái status. Nếu muốn chờ một tập các truyền thông giữa các tiến trình hoàn
thành thì dùng các hàm sau
MPI_ Waitany(int count,MPI_Request *arrayofrequest,int
*index,MPI_Status *status)
Khóa một thao tác truyền thông (gửi hoặc nhận), liên kết với một đối
tượng request trong mảng các đối tượng Request. Nếu nhiều hơn hay bằng một
thao tác đã hoàn thành, thì MPI_Waitany tùy ý lấy một đối tượng request trong
mảng đó và hoàn thành nó, MPI_Waitany sẽ trả về chỉ số của phần tử request
trong mảng và trả về trạng thái hoàn thành. Đối tượng request đó sẽ được giải
phóng và được gán giá trị MPI_REQUEST_NULL
MPI_Testany(int count,MPI_Request *array_of_requests,int *index,int
*flag,MPI_Status *status)
Nếu có một hay nhiều hơn một thao tác đã hoàn thành, nó trả về
flag=true, và chỉ số của đối tượng request trong mảng đối tượng Request, và
trạng thái của thao tác đó và đối tương trạng thái đó được giải phóng và gán giá
trị MPI_REQUEST_NULL. Ngược lại, flag=false, và
index=MPI_UNDEFINED và status=MPI_UNDEFINED, các giá trị này do
MPI định nghĩa dùng trong trường hợp các giá trị trả về không thích hợp.
MPI_ Waitall(int count,MPI_Request *arrayofrequest,MPI_Status
*arrayofstatus)
Chờ cho đến khi tất cả các thao thác có đối tượng request trong mảng
Request hoàn thành. Chỉ số trạng thái thứ i trong mảng các trạng thái trả về
trạng thái hoàn thành thứ i của thao tác. Và tất cả các đối tương trong mảng đối
tượng Request được giải phóng và được gán giá trị MPI_REQUEST_NULL,
MPI_Testall(int count,MPI_Request *array_of_request,int
*flag,MPI_Status *array_of_statuses)
Trang 100
Nếu tất cả các thao tác đã hoàn thành thì flag=true, và trả về trạng thái
status tương ứng trong mảng các trạng thái, giải phóng toàn bộ các đối tượng
request và được gán giá trị là MPI_REQUEST_NULL,
MPI_ Waitsome(int incount,MPI_Request *arrayofrequest,int
*outcount,int *offsets,MPI_Status*arrayofstatuses)
Chờ cho đến khi nhiều hơn một truyền thông được hoàn thành, liên kết
với những đối tượng request trong mảng. MPI_Waitsome trả về số lượng đối
tượng request đã hoàn thành.
MPI_Testsome(int incount,MPI_Request *array_of_request,int
*outcount,int *array_of_indices,MPI_Status *array_of_statuses)
Cũng như hàm MPI_Waitsome, ngọai trừ nó trả về ngay lập tức. Nếu không có
thao tác nào hoàn thành thì outcount=0
MPI_Iprobe(int source,int tag,MPI_Comm comm,int *flag,MPI_Status
*status)
Là hàm thuộc dạng non-blocking, trả về flag=true nếu có một thông điệp
mà có thể được nhận với những thông tin đặc tả về source, tag, comm. Lời gọi
cũng tương thích cùng thông điệp mà đã được nhận với hàm MPI_Recv (với
những tham số như thế này).
4.3.3.4. Các thủ tục liên quan đến đối tượng request
Giải phóng Request(Freeing Requests)
Một đối tượng request có thể được giải phóng dựa vào các hàm
MPI_Wait hay MPI_Test. Ngòai ra, nó còn dược giải phóng bởi sử dụng những
thao tác khác như:
MPI_Request_free(MPI_Request *request)
Nhưng các thao tác này không giải phóng được đối tượng request khi
có một sự giao tiếp liên quan đến đối tượng này vẫn tồn tại. Vì thế MPI cung
cấp thêm một hàm nữa là :
MPI_Cancel(MPI_Request *request)
Đánh dấu cho việc hủy bỏ thao tác truyền thông nonblocking (gửi hay
nhận) đang bị treo. Nó trả về ngay lập tức, có thể trước khi sự thao tác đó bị
hủy bỏ. Sau này, nó sẽ tiếp tục hoàn thành sự truyền thông mà đã đánh dấu hủy
Trang 101
bỏ. Cũng giống như các hàm MPI_IRecv(..). Hàm này cũng có thể áp dụng các
hàm liên quan đến việc chờ đợi như MPI_Wait(..) để biết hàm này đã thực hiện
xong hay chưa. Nếu sự truyền thông không bị hủy bỏ (bởi vì sự truyền thông
đã xảy ra trước khi hàm này tỏ ra hiệu quả), ngược lại thì đối tượng request sẽ
được giải phóng và trả về trạng thái thông tin đã bị hủy bỏ bằng cách sử dụng
hàm MPI_Test_cancelled(MPI_Status *status,int *flag): status lưu thông tin
của thao tác cần kiểm tra xem có phải thao tác này đã bị hủy bỏ hay chưa.
flag=true nếu xảy ra điều đó, ngược lại flag=false.
4.4. Trao đổi thông tin tập hợp
4.4.1. Đồng bộ hóa
MPI_Barrier (MPI_Comm comm)
Tạo ra một rào cản đồng bộ trong một nhóm. Mỗi tác vụ, khi tiến tới lời
gọi MPI_Barrier, thì khóa lại cho đến khi nào tất cả các tác vụ khác trong nhóm
cũng tiến tới cùng một lời gọi MPI_Barrier. Chức năng này giúp tất cả các xử
lý trong nhóm đã nhận hết được dữ liệu.
4.4.2. Di dời dữ liệu trong nhóm
MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root,
MPI_Comm comm)
Broadcast (gửi) một thông điệp từ xử lý với rank=root tới tất cả các xử
lý còn lại trong cùng một communicator (trong cùng một nhóm với nhau)
Các xử lý trong một communicator sẽ nhận dữ liệu của tiến trình gửi
broadcast
Tham số Diễn giải
Buffer địa chỉ của bộ đệm ứng dụng
Count Số lượng thực thể trong buffer
Datatype Dạng dữ liệu của buffer
Root Rank của xư lý gọi Broadcast
Comm Communicator _phạm vi ảnh hường
Trang 102
Hình 4-10 : Broadcast dữ liệu
MPI_Scatter(void *sendbuff,int sendcnt,MPI_Datatype sendtype,void
*recvbuf,int recvcnt,MPI_Datatype recvtype,int root,MPI_Comm
comm)
Phân phối và chia nhỏ thông điệp thành n phần khác nhau từ một xử lý
nguồn và gửi đến mỗi xử lý còn lại trong communicator. Hàm này giống như
gồm n hàm MPI_Send với n là số tiến trình và mỗi tiến trình đều thực hiện hàm
MPI_Recv(...). Tất cả các tham số đều quan trong với tiến trình gửi Broadcast,
còn lại các tiến trình khác chỉ quan tâm bộ đệm nhận, communicator, tiến trình
gửi, dạng dữ liệu và số dữ liêu được nhận.
Cho phép một số lượng dữ liêu được gửi đến mỗi tiến trình, bởi vì
sendcount là một mảng và còn có thêm một tham số nữa là mảng displs dùng
để quy định các địa chỉ của sendbuf được chia ra như thế nào.
Trang 103
Hình 4-11 : Ví dụ hàm Scatter
Sự mở rộng của hàm Scatter là: MPI_Scatterv(void *sendbuf,int
*sendcounts,int *displs,MPI_Datatype sendtype,void *recvbuf,int
recvcount,MPI_Datatype recvtype,int root,MPI_Comm comm)
Trái ngược với các hàm MPI_Scatter thì gồm các hàm sau đây
MPI_Gather(void *sendbuff, int sendcnt, MPI_Datatype sendtype, void
*recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
Hàm này có nhiệm vụ lấy lại tất cả các thông điệp từ mỗi tác vụ trong
một nhóm vào một tác vụ đích duy nhất.
Mỗi xử lý (kế cả xử lý ở root) đều phải gửi thông tin về sendbuf đến tiến
trình root, và tiến trình root sẽ nhận thông điệp và lưu chúng trong một danh
sách có thứ tự các định danh tiến trình (rank) .
Hình 4-12 : Hàm MPI_Gather
MPI_Allgather(void *sendbuf,int sendcount,MPI_Datatype
sendtype,void * recvbuf,int recvcount,MPI_Datatype
recvtype,MPI_Comm comm)
Cũng giống như hàm MPI_Gather(...) ngoại trừ là tất cả các tiến trình
tham gia đều có giá trị thay vì chỉ một tiến trình root sau khi thực hiện gather.
Kết qủa của hàm gọi MPI_Allgather(..) cũng như là tất cả các tiến trình thực
thi hàm MPI_Gather và đều nhận được kết quả như nhau
Trang 104
Hình 4-13 : Hàm MPI_Allgather
MPI_Alltoall(void *sendbuf,int sendcount,MPI_Datatype sendtype,void
*recvbuff,int *recvcount,MPI_Datatype recvtype,MPI_Comm comm)
là một sự mở rộng của hàm MPI_Allgather. Mỗi xử lý sẽ gửi dữ liệu
phân biệt đến mỗi trình nhận.Xử lý thứ i sẽ gửi khối thứ j đến xử lý thứ j và
được thay thế trong khối thứ i của bộ nhớ lưu trữ nhận
Hình 4-14 : Hàm MPI_Alltoall
Trang 105
4.4.3. Tính toán gộp
Các hàm ở dạng này cung cấp thêm tính toán gộp trên các xử lý với
nhau (ví dụ như tính tổng, tính giá trị lớn nhất...) các gía trị thuộc về các thành
viên của nhóm xử lý. Cũng giống như các hàm collective operation khác,
những hàm này cũng có hai dạng, đó là kết quả tính toán trả về trên một nút
hoặc kết quả tính toán trả về trên nhiều nút (nút ở đây xem như là một xử lý
hay một máy trên một mạng)
MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype
datatype, MPI_Op op, int root, MPI_Comm comm)
Tính giá trị của tất cả các tiến trình trong communicator gửi đến và sau đó đưa
giá trị tính toán đó về một tiến trình có rank=root.
Hình 4-15 : Hàm MPI_Reduce
Trang 106
4.4.3.1. Một số kiểu tính toán do MPI cung cấp
CÁC THỦ TỤC TÍNH TOÁN KIỂU DỮ LIỆU ĐƯỢC SỬ
DỤNG
MPI_MAX Tính giá trị lớn nhất integer,float
MPI_MIN Tính giá trị nhỏ nhất integer,float
MPI_SUM Tính tổng integer,float
MPI_PROD product integer,float
MPI_LAND Toán tử luận lý AND integer
MPI_BAND Toán tử dấu bit AND integer,MPI_BYTE
MPI_LOR Toán tử luận lý OR integer
MPI_BOR Toán tử dấu bit OR integer,MPI_BYTE
MPI_LXOR Toán tử luận lý XOR integer
MPI_BXOR Toán tử dấu bit XOR integer,MPI_BYTE
MPI_MAXLOC Tính giá trị lớn nhất và
thêm thông tin rank
của tiến trình chứa giá
trị lớn nhất
integer,double,vaø long double
MPI_MINLOC Tính giá trị nhỏ nhất
và thêm thông tin rank
của tiến trình chứa giá
trị nhỏ nhất
integer,double,vaø long double
4.4.3.2. Một số kiểu tính toán do người dùng định nghĩa
Để viết một hàm với chức năng do người dùng định nghĩa dựa vào thuật
toán của hàm MPI_Reduce cung cấp có thể thực hiện theo 3 bước sau :
Kiểm tra phương pháp tính toán có phù thuộc vào những yêu cầu sau
đây không?
Bước 1: Có tính kết hợp
Ví dụ a + (b+c)=(a+b)+c
Có tính giao hoán
Trang 107
Ví dụ a+b=b+a
Bước 2 : bổ sung toán tử vào hàm gộp (reduction) theo quy tắc sau
Hàm myfunc(void *in,void *inout,int *len,MPI_Datatype *datatype)
Bước 3 : Đăng ký hàm này với MPI
int commute,myop;
commute=1
MPI_Op_create(myfunc,commute,&myop)
MPI_Reduce(...,myop,..)
Hình 4-16 : Sử dụng 8 xử lý để tính giá trị tuyệt đối
Một số hàm tính toán gộp còn lại :
MPI_Allreduce(void *sendbuf,void *recvbuf,int count,MPI_Datatype
datatype,MPI_Op op,MPI_Comm comm)
Cũng giống như hàm MPI_Reduce nhưng tất cả các xử lý trong cùng một
communicator sẽ nhận giá trị tính toán được
Trang 108
Hình 4-17 Hàm Mpi-Allreduce
MPI_Reduce_scatter(void *sendbuf,void *recvbuf,int
recvcount,MPI_Datatype datatype,MPI_Op op,MPI_Comm comm)
MPI_Reduce_scatter thực hiện hai bước. Bước thứ nhất là dùng tính
toán gộp trên mỗi giá trị từ bộ đệm gửi (và dĩ nhiên là mỗi giá trị này sẽ lưu
trong một mảng). Sau đó mảng này sẽ được phân chia ra thành n đoạn (với n là
số xử lý). Đoạn thứ i sẽ chứa giá trị thứ i trong mảng đã tính toán. Và đoạn thứ
i sẽ được gửi đến xử lý thứ i và lưu trong bộ đệm nhận.
Hình 4-18 : Hàm MPI_Reduce_scatter
MPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype
datatype,MPI_Op op, MPI_Comm comm)
MPI_Scan(...) được sử dụng để thực hiện một dạng tính toán gộp theo kiểu
Reduction ở trên nhưng với tiến trình i, kết quả sẽ là thực hiện tính toán gộp
trên các tiến trình từ 0 dến i. Hình vẽ sau đây sẽ minh họa rõ hơn về điều này
Trang 109
Hình 4-19 : Hàm MPI_Scan
4.5. Các kiểu dữ liệu
4.5.1. Những kiểu dữ liệu đã được định nghĩa
Kiểu dữ liệu của MPI Kiểu dữ liệu của C
MPI_CHAR signed char
MPI_SHORT signed short int
MPI_INT signed int
MPI_LONG signed long int
MPI_UNSIGNED _CHAR unsigned char
MPI_UNSIGNED_SHORT unsigned short int
MPI_UNSIGNED unsigned int
MPI_UNSIGNED_LONG unsigned long int
MPI_FLOAT float
MPI_DOUBLE double
MPI_LONG_DOUBLE long double
MPI_BYTE
MPI_PACKED Kiểu dữ liêu khác
MPI_BYTE khác với MPI_CHAR, với một số máy tính thì MPI_CHAR
có thể là một ký tự 8 bit (1 byte), nhưng một số máy khác thì MPI_CHAR có
thể là một ký tự 2 byte (16 bit _mã Unicode chẳng hạn) còn giá trị của
MPI_BYTE là số 1 byte (8 bit) trong tất cả các trường hợp.
Trang 110
Tất cả các kiểu dữ liệu còn lại gần giống với các kiểu dữ liệu của C.
Ngoài ra còn có thêm kiểu dữ liệu MPI_Packed, một dạng dữ liệu nén mà
chúng ta sẽ đề cập sau.
4.5.2. Các kiểu dữ liệu bổ sung
Ngoài những kiểu dữ liêu do MPI cung cấp như MPI_BYTE,
MPI_DOUBLE v.v…thì MPI còn cung cấp khả năng cho việc định nghĩa chính
cấu trúc dữ liệu dựa trên các dạng dữ liệu chính. Những cấu trúc do người dùng
định nghĩa được gọi là dạng dữ liệu bổ sung.
MPI cung cấp một số phương pháp cho việc cấu trúc những kiểu dữ liệu
sau đây :
+ Contiguous
+ Vector
+ Indexed
+ Struct
4.5.2.1. Contiguous
Cấu trúc đơn giản nhất. Sản sinh ra một dạng dữ liệu mới bằng cách tạo
một số lượng những bản sao chép của một dạng dữ liệu đã có.
MPI_Type_contiguous(in count,in oldtype, out *newtype)
Hình 4-20 : MPI_Type_contiguous
4.5.2.2. Vector
Trang 111
MPI_Type_vector(int count,int blocklenght,int stride, MPI_Datatype
oldtype, MPI_Datatype*newtype)
Cũng giống như contiguous, nhưng cho phép khoanh vùng dữ liệu muốn
đăc tả .MPI_Type_hvector cũng giống như MPI_Type_vector ngoại trừ phạm
vi được đặc tả ở dạng byte.
IN :
count : số lượng block
blocklenght : số lượng của những thành phần bên trong mỗi block
stride : số lượng của những thành phần giữa vị trí bắt đầu của mỗi block
oldtype : dạng dữ liệu cũ (handle)
OUT :
newtype : dạng dữ liệu mới
Hình 4-21 : MPI_Type_vetor
4.5.2.3. Indexed
Định nghĩa dữ liệu không liên tục, khoảng cách không cố định và đều
đặn. Hàm được sử dụng là :
MPI_Type_indexed(int count,int []blocklens,int []indices,MPI_Datatype
old_type,MPI_Datatype *newtype)
Dạng dữ liệu tạo ra theo chỉ số của mảng dữ liệu đầu vào và vùng mảng
được đặc tả
Trang 112
Hình 4-22 : MPI_Type_indexed
4.5.2.4. Struct
Vấn đề đặt ra là MPI không cho truyền dữ liệu bằng kiểu cấu trúc. Do
đó, lập trình viên phải định nghĩa cấu trúc sau đó đặt tả cầu trúc đó theo dạng
byte theo sự trợ giúp của các hàm MPI.
MPI_Type_struct (int count,int []blocklens,int[]offsets,MPI_Datatype
oldtypes,MPI_Datatype *newtype)
Hình 4-23 : MPI_Type_struct
Các hàm liên quan khác đến dạng dữ liệu bổ sung :
MPI_Type_extent(MPI_Datatype,MPI_Aint* extent)
Trang 113
Trả về kích thước của dạng dữ liệu được đặc tả. Trả về kích thước theo
dạng BYTE.
MPI_Type_commit( MPI_Datatype datatype)
Đăng ký dạng dữ liệu mới với hệ thống. Đây là hàm yêu cầu cho tất cả
các hàm tạo ra kiểu dữ liệu mới trước khi sử dụng.
4.5.3. Pack và UnPack
Cung cấp những chức năng cho việc truyền nhận dữ liệu không liên tục.
Ứng dụng sẽ nén dữ liệu vào một bộ đệm liên tục trước khi gửi đi và giải nén
sau khi nhận được.
Hai hàm thường sử dụng cho việc nén và giải nén là
MPI_Pack(void* inbuf, int incount, MPI_Datatype datatype, void
*outbuf, int outsize, int *position, MPI_Comm comm)
MPI_Pack nén thông điệp với nội dung thông điệp là inbuf, incount, datatype,
comm vào không gian bộ đệm (với thông tin outbuf và outsize).
Bộ đệm vào (inbuf) có thể là bất kỳ bộ đệm truyền thông (mà được cho phép
trong giao tiếp gửi MPI_SEND) và dữ liệu ra (output buffer) là một vùng lưu
trữ liên tục chứa outsize bytes, bắt đầu với địa chỉ outbuf.
MPI_Unpack(void* inbuf, int insize, int *position, void *outbuf, int
outcount, MPI_Datatype datatype, MPI_Comm comm)
Ngược lại với chức năng của hàm MPI_Pack, MPI_Unpack giải nén một
thông điệp được đặc tả thông tin (giá trị inbuf,kích thước insize) vào bộ đệm
nhận được đặt tả với thông tin (giá trị outbuf,kích thước outsize, dạng dữ liệu
datatype). Bộ đệm đầu ra thuộc bất kỳ dạng dữ liệu nào được truyền thông
trong hàm nhận MPI_Recv. Bộ đệm đầu vào (input buffer) là dạng dữ liệu liên
tục chứa insize bytes, bắt đầu với địa chỉ của inbuf.
Việc phân biệt ngữ nghĩa giữ kiểu dữ liệu bổ sung và kiểu dữ liệu
MPI_PACKED rất khó. Tuỳ theo ngữ cảnh mà người dùng tự chọn cho mình
cách biểu thị tốt nhất cho bài toán tối ưu về mặt ngữ nghĩa và truyền thông
trong các thuật toán cụ thể
Trang 114
Chương 5. Thử nghiệm các thuật toán lý thuyết đồ thịCác chương trình mà nhóm chúng em test ở đây sử dụng các máy với cấu hình
như sau:
• Khi trên 1 máy : Pentium IV 3GHz, RAM 512MB
• Khi trên 2 máy : Pentium IV 3GHz, RAM 512MB và Pentium IV
800 MHz, RAM 256MB
5.1. Các khái niệm cơ bản
5.1.1. Đồ thị
Một đồ thi G=(V,E) trong đó V là tập các đỉnh của đồ thị, E là tập các
cạnh của đồ thị, mỗi cạnh sẽ là sự liên kết của hai đỉnh.
Chỉ đề cập đến hai loại đồ thị là :
Đồ thị vô hướng: nếu những cạnh không có thứ tự hai chiều.
Hai đỉnh u và v trong một đồ thị vô hướng G được gọi là liền kề hay
(láng giềng) nếu u ,v là một cạnh của G. Nếu e=(u,v) thì e được gọi là cạnh liên
thuộc với các đỉnh u và v. Cạnh e cũng được gọi là cạnh nối các đỉnh u và v.
Các đỉnh u và v được gọi là các điểm đầu mút của cạnh (u,v).
Đồ thị hữu hướng khi cạnh có hai chiều nối hai đỉnh khác nhau.
Khi (u,v) là cạnh của đồ thị có hướng G, thì u được gọi là nối tới v, và v
được gọi là được nối từ u. Đỉnh u gọi là đỉnh đầu, đỉnh v gọi là đỉnh cuối của
cạnh (u,v). Đỉnh đầu và đỉnh cuối của khuyên là trùng nhau.
Một đồ thị trọng số là đồ thị có độ dài cho mỗi cạnh
Ký hiệu: G(V,E, w)
Ma trận liền kề: A=(ai,j) ,là một mảng 2 chiều với thông tin như sau
nếu cạnh (i,j) tồn tại thì ai,j=1(hay độ dài của cạnh ) ngược lại thì ai,j=0.
5.1.2. Đường đi
Đường đi từ đỉnh u đến đỉnh v là một tập thứ tự các đỉnh <v0,v1,...,vk,
trong đó v0=v và vk=v và (vi,vi+1) thuộc tập cạnh E với mọi i từ 0 đến k
Chiều dài của đường đi là tổng giá trị độ dài các cạnh
Đường đi (u,v):
Trang 115
Nếu đường đi tồn tại , u tiến tới v
Đơn giản nếu tất cả các đỉnh trung gian đi qua là phân biệt
Là khuyên nếu vo=vk
G là đồ thị liên thông nếu có một đường đi từ một đỉnh đến bất kỳ các đỉnh còn
lại
5.2. Dijkstra
5.2.1. Tuần tự
Thuật toán do E.Dijkstra, nhà toán học người Hà Lan, đề xuất vào năm
1959.
Các bước thực hiện thuật toán Dijkstra:
Đầu tiên gán cho đỉnh α nhãn bằng 0 và các đỉnh khác là ∞. Ta ký hiệu
L(α)=0 và L(v)= ∞ cho tất cả các đỉnh khác (bước lặp thứ 0). Các nhãn này là
độ dài của đường đi ngắn nhất từ đỉnh α tới các đỉnh này, trong đó đường đi
này chỉ chứa đỉnh α. (Vì không có đường đi từ α tới các đỉnh khác α nên ∞ là
độ dài đường đi ngắn nhất giữa α và các đỉnh này). Theo thuật toán Dijkstra ta
sẽ xây dựng tập đặc biệt các đỉnh. Gọi Sk là tập này sau bước lặp thứ k của thủ
tục gán nhãn. Chúng ta bắt đầu bằng So=Φ. Tập Sk được tạo thành từ Sk-1 bằng
cách thêm vào đỉnh u không thuộc Sk-1 có nhãn nhỏ nhất. Khi đỉnh u được gộp
vào Sk chúng ta sửa đổi nhãn của các đỉnh không thuộc Sk sao cho Lk(v), nhãn
của v tại bước k, là độ dài của đường đi ngắn nhất từ α tới v mà đường đi này
chỉ chứa các đỉnh thuộc Sk (tức là các đỉnh đã thuộc tập đặc biệt các đỉnh cùng
với u)
Giả sử v là một đỉnh không thuộc Sk. Để sửa nhãn của v ta thấy Lk(v) là độ dài
của đường đi ngắn nhất từ α tới v và chỉ chứa các đỉnh thuộc Sk. Để sửa đổi
nhãn ta lưu ý rằng đường đi ngắn nhất từ α tới u ở bước k-1 cùng với cạnh
(u,v). Nói cách khác ta có.
L(a,v) = min(Lk-1(a,v), Lk-1(a,u) + w(u,v))
Trang 116
Thủ tục này được lặp bằng cách liên tiếp thêm các đỉnh vào tập đặc biệt
các đỉnh cho tới khi đạt tới đỉnh z. Khi thêm z vào tập đặc biệt các đỉnh thì
nhãn của nó bằng độ dài của đường đi ngắn nhất từ α tới z.
Sau đây là một ví dụ cụ thể minh họa thuật toán Dijkstra trên một đồ thị vô
hướng 6 đỉnh
Hình 5-1.1.
Hình 5-1.2.
Trang 117
Hình 5-1.3.
Hình 5-1.4.
Trang 118
Hình 5-1.5
Hình 5-1.6
Hình 5-1. Thuật toán Dijkstra tuần tự
Trang 119
5.2.2. Song song
Thuật toán Dijkstra tuần tự có rất nhiều điểm dễ song song hoá. Do đó
thuật toán này đã được các nhà lập trình song song hóa rất nhiều. Cụ thể sau
đây là cách song song hóa của thuật toán Dijkstra tuần tự.
Lúc này chúng ta nghĩ rằng không phẩi thực thi thuật toán trên một bộ
xử lý nữa mà phân phối các công việc khác nhau cho mỗi bộ xử lý khác nhau
thực hiện. Mỗi bộ xử lý sẽ đảm nhận một số đỉnh của đồ thị cùng với ma trận
mô tả quan hệ của các đỉnh đó với các đỉnh còn lại.
• Triển khai thuật toán
p là số bộ xử lý, n là số đỉnh của đồ thị
Mỗi bộ xử lý quản lý n/p số đỉnh
Nếu n/p dư lẻ thì P0 đến Pn-2 sẽ quản lý n/p số đỉnh
Số đỉnh còn lại sẽ do Pn-1 quản lý
Mỗi bộ xử lý sẽ lưu một ma trận với số cột là số đỉnh do chính Pi quản lý và số
dòng là n (tương ứng với số đỉnh của đồ thị) liên quan đến ma trận liền kề A
Tương ứng với các đỉnh đó sẽ gồm mảng mô tả độ dài trọng số của đỉnh Li[]
Hình 5-2 : Thuật toán Dijkstra song song
Các bước thực hiện song song hoá như sau :
Bước 1:
Trang 120
Khởi tạo tập đỉnh Vt={r}, L[k]=∞ ∀k , L[r]=0;
Lấy dữ liệu từ tập tin
Phân chia dữ liệu trong ma trận trọng số A[][] đến các bộ xử lý.
Với mỗi bộ xử lý sẽ có một ma trận con tương đương với một ma
trận con của A nhận dữ liệu.
Mỗi Pi ngoại trừ P0 sẽ lưu một mảng đỉnh riêng cho mình Vi
Bước 2:
Từ bộ xử lý master, P0 broadcast đỉnh được chọn là r đến các bộ
xử lý còn lại.
Bước 3:
Lặp cho đến khi nào đỉnh đích đã được chọn
Mỗi Pi sẽ cập nhật mảng L[] với L[k] = Min[L[k], L(Selected) +
W(selectedV,k)] với mọi k thuộc về tập đỉnh Vi
Mỗi Pi sẽ tính toán Min Li = Min(trong số mảng Li)
Thực hiện việc tính Min trên tất cả các bộ xử lý và lấy giá trị nhỏ
nhất. Sau đó chọn được đỉnh có độ dài nhỏ nhất là SelectedV
P0 sẽ broadcast giá trị SelectedV đến các bộ xử lý còn lại
P0 sẽ đưa đỉnh được chọn vào tập Vt
5.2.3. Thực nghiệm chương trình
Tuần tự
00.010.020.030.040.050.060.07
300 Ñænh 700 Ñænh 1000 Ñænh
Soá ñænh cuûa ñoà thò
Tho
i gia
n xö
û lyù
(gi
aây)
Song song (trên 2 máy)
Kiểm tra với đồ thị thưa
Trang 121
02468
101214
2 4 6 8 10 12 14 16
Soá tieán trình
Thô
øi gi
an x
öû ly
ù (gi
aây)
300 Ñænh700 Ñænh1000 Ñænh
Kiểm tra với đồ thị vừa
0
24
6
810
12
2 4 6 8 10 12 14 16
Soá tieán trình
Thô
øi gi
an x
öû ly
ù (gi
aây)
300 Ñænh700 Ñænh1000 Ñænh
Thử nghiệm với đồ thị đủ
0
5
10
15
2 4 6 8 10 12 14 16
Soá tieán trình
Thôøi
gia
n xö
û lyù (g
iaây)
300 Ñænh700 Ñænh1000 Ñænh
Trang 122
Đánh giá kết quả thu được: việc triển khai trên hệ thống LAM/MPI với độ
phức tạp của thuật toán Dijkstra là O(n2) kết quả thu được cho thấy việc triển
khai chương trình với thuật toán có độ phức tạp nhỏ, thời gian dùng cho việc
truyền thông chiếm dụng nhiều gây lãng phí cho thời gian thực hiện chương
trình. Do đó kết quả khi thực hiện song song có kết quả không tốt, số tiến trình
gia tăng kéo theo thời gian xử lý cũng tăng theo.
5.3. Prim
5.3.1. Tuần tự
Do Robert Prim đưa ra vào năm 1957, mặc dù ý tưởng cở bản của nó đã
có từ sớm hơn rất nhiều. Để thực hiện thuật toán Prim, ta bắt đầu bằng việc
chọn một cạnh bất kỳ có trọng số nhỏ nhất, đặt nó vào cây khung. Lần lượt
ghép vào cây và không tạo ra chu trình trong cây. Thuật toán sẽ dừng khi n-1
cạnh đã được ghép vào cây.
b1:
b2:
b3:
Trang 123
b4:
b5:
b6:
b7:
Trang 124
b8:
b9:
Hình 5-3. Thuật toán Prim tuần tự
5.3.2. Song song
Do hai thuật toán Dijkstra và Prim gần giống nhau về mặt bản chất đó là
cùng tìm giá trị nhỏ nhất. Đối với Prim đó là cạnh có trọng số nhỏ nhất, còn đối
với Dijkstra là đỉnh có độ dài từ đỉnh nguồn đến nó nhỏ nhất. Nên về mặt song
song hóa thuật toán Prim cũng tương tự như thuật toán Dijkstra
• Triển khai thuật toán
p bộ xử lý, n = số đỉnh của đồ thị
Mỗi bộ xử lý quản lý n/p số đỉnh
Nếu n/p dư lẻ thì P0 đến Pn-2 sẽ quản lý n/p số đỉnh
Số đỉnh còn lại sẽ do Pn-1 quản lý
Trang 125
Mỗi bộ xử lý sẽ lưu một ma trận với số cột là số đỉnh do chính Pi quản lý và số
dòng là n (tương ứng với số đỉnh của đồ thị) của ma trận liền kề A
Hình 5-3 : Thuật toán Prim song song
Các bước xử lý thuật toán :
Bước 1:
Khởi tạo tập đỉnh Vt={r}, L[k]=∞ ∀k ,L[r]=0;
Lấy dữ liệu từ tập tin
Phân chia dữ liệu trong ma trận trọng số A[][] đến các bộ xử lý. Với mỗi bộ xử
lý sẽ có một ma trận con tương đương với một ma trận con của A nhận dữ liệu
Mỗi Pi ngoại trừ P0 sẽ lưu một mảng đỉnh riêng cho mình Vi
Bước 2:
Từ bộ xử lý master, P0 broadcast đỉnh được chọn là r đến các bộ xử lý còn lại.
Bước 3:
Lặp cho đến khi nào đã có n đỉnh được chọn (với n là số đỉnh của đồ thị)
Mỗi Pi sẽ cập nhật mảng L[] với L[k] = Min[L[k], W(selectedV,k)] với mọi k
thuộc về tập đỉnh Vi
Mỗi Pi sẽ tính toán Min Li = Min(trong số mảng Li)
Thực hiện việc tính Min trên tất cả các bộ xử lý và lấy giá trị nhỏ nhất. Sau đó
chọn được đỉnh có độ dài nhỏ nhất là SelectedV
Trang 126
P0 sẽ broadcast giá trị SelectedV đến các bộ xử lý còn lại
P0 sẽ đưa đỉnh được chọn vào tập Vt
5.3.3. Thực nghiệm chương trình
Tuần tự :
Thực nghiệm với loại đồ thị đủ có số đỉnh từ 300, 700, và 1000 đỉnh
00.010.020.030.040.050.060.070.080.09
300 Ñænh 700 Ñænh 1000 Ñænh
Soá ñænh cuûa ñoà thò
Thô
øi gi
an x
öû l
yù (
giaâ
y)
Song song :
Thử nghiệm với đồ thị thưa
0
5
10
15
20
2 4 6 8 10 12 14 16
Soá tieán trình
Thô
øi gi
an (
giaâ
y)
300 Ñænh700 Ñænh1000 Ñænh
Thử nghiệm với đồ thị vừa
Trang 127
0
5
10
15
20
2 4 6 8 10 12 14 16
Soá tieán trình
Thô
øi gi
an (
giaâ
y)300 Ñænh700 Ñænh1000 Ñænh
Thử nghiệm với đồ thị đủ
0
5
10
15
20
2 4 6 8 10 12 14 16
Soá tieán trình
Thôøi
gia
n (g
iaây)
300 Ñænh
700 Ñænh
1000 Ñænh
Đánh giá kết quả thu được: Giống như Dijkstra, việc triển khai trên hệ
thống LAM/MPI với độ phức tạp của thuật toán Prim là O(n)2 kết quả thu được
cho thấy việc triển khai chương trình có thuật toán có độ phức tạp nhỏ, thời
gian dùng cho việc truyền thông chiếm dụng nhiều gây lãng phí cho thời gian
thực hiện chương trình. Kết quả thu được khi thực thi cũng không đạt kết quả
như mong đợi do vấn đề về chi phí giao tiếp.
Trang 128
5.4. Bellman – Ford
5.4.1. Tuần tự
Thuật toán Bellman – Ford giải quyết bài toán tìm đường đi ngắn nhất
trong trường hợp tổng quát hơn so với thuật toán Dijkstra, trong đó trọng số
của các cạnh nối có thể là số âm. Cho một đồ thị G=(V, E) có hướng và trọng
số, với đỉnh nguồn s và hàm trọng số w : E→R, thuật toán trả về giá trị kiểu
boolean cho biết từ đỉnh nguồn có thể đến được mạch âm hay không. Nếu có
thì thuật toán sẽ kết thúc mà không có lời giải, còn nếu không sẽ kết xuất tất cả
các con đường ngắn nhất cùng với chiều dài của chúng.
Giống như thuật toán Dijkstra, thuật toán Bellman – Ford cũng sử dụng
kỹ thuật relaxation, bằng cách ngày càng giảm chiều dài của đường đi ngắn
nhất từ đỉnh s đến các đỉnh v∈V cho đến khi đạt được giá trị ngắn nhất. Thuật
toán trả về giá trị TRUE khi và chỉ khi từ đỉnh gốc không đến được mạch âm.
BELLMAN-FORD(G, w, s)
INITIALIZE-SINGLE-SOURCE(G, s)
for i←1 to |V[G]|-1
do for each edge (u, v) ∈E[G]
do RELAX(u, v, w)
for each edge (u, v) ∈E[G]
do if d[v] > d[u] + w(u, v)
then return FALSE
return TRUE
b1:
Hình a
Trang 129
b2
Hình b
b3
Hình c
b4
Hình d
Trang 130
b5
Hình e
Hình 5-4: Thuật toán Bellman-Ford tuần tự
Hình bên trên thể hiện thuật toán Bellman-Ford với 5 đỉnh. Sau
khi thực hiện phép khởi tạo thông thường, thuật toán thực hiện qua |V|-1 bước
qua các cạnh của đồ thị. Hình (b) và (e) cho thấy trạng thái của thuật toán sau
mỗi bước. Sauk hi thực hiện |V|-1 bước , thuật toán sẽ tiến hành kiểm tra mạch
âm và trả về giá trị Boolean thích hợp.
Thuật toán Bellman-Ford có chi phí là O(V,E), bởi chi phí cho
việc khởi tạo là O(V), còn từng bước sẽ tốn O(E), và dòng lặp cuối cùng cũng
tốn chi phí là O(E).
5.4.2. Song song
Mô tả chương trình
Như đã đề cập ở trên ta có 2 khái niệm cần được phân biệt rõ, là xây
dựng chương trình song song từ một thuật toán song song cụ thể đã được thực
nghiệm và kiểm tra tính đúng đắn, còn một cách khác để cài đặt một chương
trình song song là tiến hành song song hóa các phần trong chương trình tuần tự.
Trong thực tế, phần lớn người ta thường sử dụng cách thứ hai do việc thiết kế
ra một thuật toán song song là điều rất khó khăn và cần nhiều thời gian làm
việc.
Chương trình song song cài đặt thuật toán Bellman-Ford được dùng ở
đây là tiến hành theo cách thứ hai như đề cập phần trên.
Đặc điểm chương trình:
Trang 131
o Số bộ xử lý tham gia là biến động tùy thuộc vào người sử dụng.
o Nội dung ma trận kề của đồ thị được nhận vào từ tập tin.
o Có thể thay đổi các tham số của chương trình như : đỉnh nguồn,
đỉnh đích, tên tập tin nhập liệu.
Thực hiện
Quy ước :
+ ta có thể hiểu khái niệm tiến trình ở đây là trên một bộ xử lý, số
lượng các tiến trình tham gia cũng là số bộ xử lý cần có (cũng là số máy trạm
nếu trên một máy chỉ có một bộ xử lý).
+ P là ma trận gồm 2 dòng, có số cột bằng với số đỉnh của đồ thị,
dùng để lưu đường đi ngắn nhất.
+ L là ma trận kề lưu nội dung của đồ thị.
Các bước thuật toán
b1: khởi tạo ma trận P và L.
b2: tiến trình chính gửi cho các tiến trình con một số cột của ma trận L,
tùy vào số máy để chạy chương trình.
b3: tiến trình chính broadcast 1 dòng của ma trận P, rồi nhận lại P sau
khi các tiến trình con thực hiện tính toán, chương trình kết thúc khi:
2 dòng của ma trận P tương tự nhau, lúc đó kết luận từ đỉnh nguồn có thể đến
được mạch âm, bài toán kết thúc mà không có lời giải.
Khi số lần thực thi bước 3 lớn hơn số đỉnh của đồ thị, chương trình kết xuất
đường đi ngắn nhất từ đỉnh nguồn đến các đỉnh còn lại theo như trong ma trận
P.
Trang 132
Hình 5-5 : Thuật toán Bellman-Ford song song
5.4.3. Thực nghiệm chương trình
Tuần tự
Kiểm tra chương trình Bellman tuần tự trên một máy với các loại đồ thị
đủ có mạch âm với số đỉnh tương ứng là 300 đỉnh, 700 đỉnh và 1000 đỉnh
020406080
100120140
300 Ñænh 700 Ñænh 1000 Ñænh
Soá ñænh cuûa ñoà thò
Thô
øi gi
an x
öû ly
ù (g
iaây
)
Trang 133
Điều này chứng tỏ với đồ thị có mạch âm, độ phức tạp của thuật toán
Bellman là O(n)3 làm cho thời gian thực thi chương trình càng lớn, số đỉnh
càng nhiều thì thời gian thực thi càng cao.
Song song
Thử nghiệm thuật toán Bellman trên môi trường LAM/MPI với 2 máy, kiểm tra
3 loại đồ thị là đồ thị thưa và đồ thị đủ
Đồ thị thưa
0
0.2
0.4
0.6
0.8
1
2 4 6 8 10 12 14 16
Soá tieán trình
Thô
øi gi
an x
öû ly
ù (gi
aây)
300 Ñænh700 Ñænh1000 Ñænh
Đồ thị vừa
00.5
11.5
22.5
2 4 6 8 10 12 14 16
So á tie án trình
Thô
øi gi
an x
öû l
yù
(gia
ây) 300 Ñænh
700 Ñænh
1000 Ñænh
Trang 134
Đồ thị đủ
0
20
40
60
80
100
120
2 4 6 8 10 12 14 16
Soá tieán trình
Thô
øi gi
an x
öû ly
ù (gi
aây)
300 Ñænh700 Ñænh1000 Ñænh
Đánh giá kết quả: kết quả kiểm tra cho thấy với thuật toán Bellman-Ford
độ phức tạp là O(n)3, áp dụng trên hệ LAM/MPI với 2 máy kết quả thu được rất
khả quan trong việc viết chương trình song song hoá cho các bài toán có độ
phức tạp càng cao, thực thi trên nhiều máy. Kết quả cho thấy sử dụng nhiều
tiến trình trong việc thực thi chương trình thì thời gian tiêu tốn ít hơn so với
chương trình tuần tự một tiến trình, và càng nhiều tiến trình thì chương trình
thực hiện được nhanh hơn. Khi chỉ dùng 2 tiến trình để thực thi thì chi phí tốn
kém rất nhiều so với khi dùng 4 tiến trình để thực hiện, còn với số tiến trình
khi lớn hơn 6 thì thời gian xử lý giảm không nhiều so với khi có 4 tiến trình.
Điều này có thể lý giải do chương trình MPI thực hiện theo cơ chế Master-
Slave, nên khi thực thi 2 tiến trình thì thực sự chỉ có 1 tiến trình con là tính toán
để gửi trả kết quả về cho master. Bên cạnh đó do chạy tiến trình chính trên
máy có cấu hình mạnh hơn, nên thời gian cho tiến trình client khá cao. Nhưng
khi thực thi trên 4 tiến trình trở lên thì số client này gia tăng, dẫn đến làm giảm
thời gian xử lý, nhưng cũng vì chỉ có 2 máy nên khi số tiến trình càng tăng thì
cũng kéo theo chí phí truyền thông và đồng bộ hóa. Do đó thời gian đạt được
khi số tiến trình lớn hơn 4 không cách nhau nhiều.
5.5. Đánh giá chung Nhìn chung kết quả thu được trên thuật toán Prim và Dijkstra không
được như mong đợi, bằng chứng là khi số tiến trình gia tăng cũng kéo theo gia
Trang 135
tăng thời gian xử lý. Điều này có thể được lý giải do 2 thuật toán này có độ
phức tạp không cao O(n2), nên thực sự chi phí xảy ra là do giao tiếp truyền
thông giữa các tiến trình.
Nhưng khi thực hiện trên thuật toán Bellman, một thuật toán có độ phức
tạp rất lớn O(n3), thì kết quả thu được đã đạt được như mong đợi. Thời gian
thực thi song song tốt hơn rất nhiều so với khi thực thi tuần tự, và càng tốt hơn
khi gia tăng số tiến trình xử lý.
Tuy chỉ có thể thực hiện trên 2 máy nhưng kết quả đạt được với
Belman khá tốt, điều này cho thấy tiềm năng rất lớn của lập trình song và phân
bố. Nếu có thể được triển khai các chương trình có thuật toán với độ phức tạp
càng lớn trên một môi trường với nhiều máy tính kết nối thì chúng em tin
tưởng rằng chương trình sẽ được thực thi nhanh hơn rất nhiều so với việc
chương trình chỉ được thực thi trên một hay 2 máy.
Trang 136
Chương 6. Tổng kết
6.1. Kết luận
Dựa trên các kiến thức đã tìm hiểu được về tính toán lưới, cách thức lập
trình trên môi trường song song và phân tán, cũng như các môi trường hỗ trợ
phát triển, đề tài đã đat được mục tiêu đề ra là nghiên cứu về tính toán lưới và
thực nghiệm trên một số thuật toán lý thuyết đồ thị.
Mặc dù thời gian thực hiện có hạn, bên cạnh đó gặp phải một số khó
khăn trong việc triển khai ứng dụng, do đây là một đề tài khá mới ít được quan
tâm phát triển trước đây, nhưng chúng em cũng cố gắng thực hiện để đạt được
các yêu cầu đề ra.
Các chương trình viết ra đều có khả năng thực hiện trên nhiều máy với
số máy xử lý tùy biến và thực hiện đúng kết quả cần thiết.
Chúng em hy vọng sẽ tiếp tục cải tiến chương trình, tối ưu các thuật toán
để đạt được kết quả tốt nhất, tận dụng được sức mạnh của các máy con để giải
quyết vấn đề. Bên cạnh đó, chúng em cũng hy vọng có thể triển khai trên các
hệ thống lớn hơn.
6.2. Hướng phát triển
Tương lai của tính toán song song và phân bố, và xa hơn nữa là tính toán
lưới vẫn còn rất lớn. Trên thế giới hiện nay người ta vẫn đang tiếp tục nghiên
cứu mạnh mẽ nhằm có thể tận dụng được khả năng của các hệ thống máy tính
lớn trên thế giới, góp phần trong công tác nghiên cứu khoa học cũng như
thương mại.
Do trong thời hạn cho phép cũng như khả năng và kiến thức hiện nay
vẫn chưa thực sự phát huy được hết khả năng của tính toán lưới, vì thế đề tài
hiện còn khả năng phát triển rất lớn.
• Cải tiến chương trình
Tìm hiểu sâu hơn về thư viện MPI để phát huy tiềm năng rất lớn của nó,
bên cạnh đó cũng cần thực hiện một số phương pháp tối ưu như giảm chi phí
Trang 137
do tính toán, truyền tải thông tin…Bên cạnh đó nếu có điều kịện sẽ sử dụng
trên môi trường hỗ trợ tính toán lưới phổ biến nhất hiện nay là Globus.
• Triển khai thực tế
Do hạn chế về cơ sở vật chất nên các chương trình chưa được triển khai
trên các hệ thống lớn, thực tế để qua đó có thể đánh giá đúng được khả năng
của chương trình. Do đó chúng em hy vọng có thể tiếp tục phát triển được đề
tài để tận dụng được sức mạnh của tính toán lưới, đem lại hiệu quả cao trong
công tác nghiên cứu khoa học và áp dụng vào thực tế.
Trang 138
Tài liệu tham khảo Tài liệu viết:
[1] Wolfgang Gentzsch, Grid Computing : A New Technology for the
Advanced Web, Sun Microsystem Inc, 2001
[2] Ananth Gramma, Anshul Gupta, George Karypis, Vipin Kumar :
Introduction to Parallel Computing 2nd, Addison Wesley, USA, 2003
[3] Behrooz Parhami, Introduction to Parallel Processing Algorithms and
Architectures, Kluwer Academic, 2002
[4] Fran Berman, Anthony J.G.Hey, Geoffrey C.Fox, Grid Computing Making
the Global Infrastructure a Reality, Wiley, 2003
[5] IBM RedBooks, Introduction to Grid Computing with Globus, 2003
[6] Graeme S.McHale, Parallel Programming on Linux Networks Using MPI &
PVM
[7] Mark Baker, Rajkumar Buyya, Domenico Laforenza, Grids and Grid
technologies for wide-area distributed computing, Software – Practice and
Experience, 2002
[8] 7.1.1 Lam Install ,LAM/MPI Team Open Systems LAb
[9] 7.1.1 Lam User Guide,LAM/MPI Team Open Systems LAb
Website:
[10] Global Grid Forum, http://www.gridforum.org
[11] Ian Foster, Designing and Building Parallel Programs, 1995,
http://www.mcs.anl.gov/people/foster/
[12] http://www.lam-mpi.org/
[13] http://www-unix.mcs.anl.gov/mpi/mpich
[14] http://www.mpi.org/
[15] http://www.mpi-forum.org/
[16] Application of Parallel Computers http://crd.lbl.gov/~dhbailey/cs267/
[17] http://www.cs.uncc.edu/~abw/parallel/par_prog/resources.htm