Tải bản đầy đủ (.pdf) (73 trang)

Các cấu trúc khung cho lập trình đa lõi

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (938.11 KB, 73 trang )

BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
---------------------------------------

LÊ ĐỨC TÙNG

CÁC CẤU TRÚC KHUNG CHO LẬP TRÌNH ĐA LÕI

Chuyên ngành: CÔNG NGHỆ THÔNG TIN

LUẬN VĂN THẠC SĨ KHOA HỌC
CÔNG NGHỆ THÔNG TIN

NGƯỜI HƯỚNG DẪN KHOA HỌC
TIẾN SĨ NGUYỄN HỮU ĐỨC

Hà Nội - 2010


Lời cam đoan
Tôi - Lê Đức Tùng - xin cam đoan:
• Luận văn tốt nghiệp Thạc sĩ này là công trình nghiên cứu của bản thân
tôi dưới sự hướng dẫn của TS.Nguyễn Hữu Đức.
• Các kết quả trong Luận văn tốt nghiệp là trung thực, không phải sao
chép toàn văn của bất kỳ công trình nào khác.
Hà Nội, ngày 05 tháng 10 năm 2010

Lê Đức Tùng

i



Mục lục

Lời cảm ơn

v

1 Giới thiệu luận văn

1

1.1

Lý do chọn đề tài . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.2

Mục đích nghiên cứu của luận văn . . . . . . . . . . . . . . . .

4

1.3

Luận điểm cơ bản và đóng góp mới . . . . . . . . . . . . . . .

4

1.4


Cấu trúc luận văn . . . . . . . . . . . . . . . . . . . . . . . . .

5

2 Lập trình song song theo kiểu cấu trúc khung
2.1

Đặt vấn đề . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2

Cấu trúc giải thuật khung - Hướng tiếp cận có cấu trúc để

7
7

quản lý các tính toán song song . . . . . . . . . . . . . . . . . 10
2.3

2.4

Cấu trúc khung chia-trị . . . . . . . . . . . . . . . . . . . . . . 14
2.3.1

Đặt vấn đề

. . . . . . . . . . . . . . . . . . . . . . . . 14

2.3.2


Hướng tiếp cận ZAPP . . . . . . . . . . . . . . . . . . 14

2.3.3

Hướng tiếp cận FDDC . . . . . . . . . . . . . . . . . . 16

Cấu trúc khung kết hợp lặp . . . . . . . . . . . . . . . . . . . 17

ii


0.0

MỤC LỤC

2.5

2.6

2.4.1

Đặt vấn đề

. . . . . . . . . . . . . . . . . . . . . . . . 17

2.4.2

Đặc tả cấu trúc khung kết hợp lặp . . . . . . . . . . . 18


2.4.3

Các vấn đề liên quan đến thực thi song song . . . . . . 20

Cấu trúc khung cluster . . . . . . . . . . . . . . . . . . . . . . 22
2.5.1

Đặt vấn đề

. . . . . . . . . . . . . . . . . . . . . . . . 22

2.5.2

Đặc tả cấu trúc khung cluster . . . . . . . . . . . . . . 23

Cấu trúc khung hàng đợi công việc . . . . . . . . . . . . . . . 25
2.6.1

Đặt vấn đề

. . . . . . . . . . . . . . . . . . . . . . . . 25

2.6.2

Đặc tả cấu trúc khung hàng đợi công việc . . . . . . . 26

3 Nghiên cứu các lý thuyết tính toán trên giải thuật nhằm áp
dụng xây dựng cấu trúc khung

29


3.1

Tổng quan về khái niệm Tính toán trên giải thuật . . . . . . . 30

3.2

Phương pháp mới thiết kế các cấu trúc khung song song . . . 32

3.3

Cấu trúc khung song song cho kiểu dữ liệu Danh sách . . . . . 34

3.4

3.3.1

Định nghĩa đại số cho kiểu dữ liệu danh sách . . . . . . 34

3.3.2

Homomorphism cho danh sách song song . . . . . . . . 35

3.3.3

Các cấu trúc khung trên danh sách . . . . . . . . . . . 36

Cấu trúc khung song song cho kiểu dữ liệu Ma trận . . . . . . 37
3.4.1


Định nghĩa đại số cho mảng hai chiều . . . . . . . . . . 37

3.4.2

Homomorphism cho mảng hai chiều . . . . . . . . . . . 38

3.4.3

Cấu trúc khung song song trên ma trận hai chiều . . . 39

4 Nghiên cứu xây dựng cấu trúc khung cho cấu trúc dữ liệu

iii


0.0

MỤC LỤC
HTA
4.1

4.2

45

Cấu trúc dữ liệu HTA . . . . . . . . . . . . . . . . . . . . . . 45
4.1.1

Định nghĩa và phân loại cấu trúc dữ liệu HTA . . . . . 45


4.1.2

Một số khái niệm liên quan đến cấu trúc dữ liệu HTA . 49

4.1.3

Một số cách xây dựng cấu trúc dữ liệu HTA . . . . . . 52

Định nghĩa đại số mới cho cấu trúc dữ liệu HTA . . . . . . . . 54
4.2.1

Định nghĩa . . . . . . . . . . . . . . . . . . . . . . . . 54

4.2.2

Một số tính chất của cấu trúc HTA đại số . . . . . . . 56

4.3

Homomorphism . . . . . . . . . . . . . . . . . . . . . . . . . . 57

4.4

Xây dựng các cấu trúc khung cho cấu trúc dữ liệu HTA . . . . 58
4.4.1

Cấu trúc khung map . . . . . . . . . . . . . . . . . . . 58

4.4.2


Cấu trúc khung reduce . . . . . . . . . . . . . . . . . . 59

4.4.3

Cấu trúc khung zipwith . . . . . . . . . . . . . . . . . . 59

5 Kết luận và hướng phát triển

61

5.1

Kết luận . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

5.2

Hướng phát triển . . . . . . . . . . . . . . . . . . . . . . . . . 62

Tài liệu tham khảo

64

Danh sách hình vẽ

66

iv


Lời cảm ơn

Tôi xin gửi lời cảm ơn sâu sắc đến Tiến sĩ Nguyễn Hữu Đức, người đã
hướng dẫn tận tình và theo dõi sát sao trong qúa trình làm luận văn. Chính
Thầy là người đã đưa ra ý tưởng xây dựng nên cấu trúc dữ liệu HTA song
song là điểm mới trong luận văn tốt nghiệp này.
Tôi xin gửi lời cảm ơn chân thành đến Phó giáo sư, Tiến sĩ Nguyễn
Thanh Thủy, Thầy đã góp ý cho tôi ngay từ khi mới bắt đầu làm đề tài,
làm rõ các hướng đi cần thiết cho đề tài này.
Chuyến đi làm việc 5 tháng tại Viện Tin học Nhật Bản (National Institute
of Informatics) mang lại cho tôi nhiều điều. Tôi xin gửi lời cảm ơn Giáo sư
Zhenjiang Hu. Giáo sư đã hướng dẫn và trao đổi với tôi tận tình trong thời
gian làm việc về vấn đề Lý thuyết tính toán trên giải thuật cũng như thư viện
lập trình SkeTo do nhóm của ông phát triển tại Viện Tin học Nhật Bản và
Đại Học Tokyo.
Tôi xin gửi lời cảm ơn đến Trung tâm tính toán hiệu năng cao ĐHBKHN, nơi tôi đang làm việc, Trung tâm đã hỗ trợ tôi rất nhiều về mặt
chuyên môn cũng như điều kiện cơ sở vật chất để hoàn thành luận văn này.
Tôi xin gửi lời cảm ơn đến Phòng thí nghiệm Takeichi - Đại học Tokyo
nơi tạo điều kiện cho tôi có các buổi thảo luận hàng tuần với nhóm nghiên
cứu ở đó trong thời gian làm việc với giáo sư Zhenjiang Hu.
Cuối cùng, con muốn cảm ơn gia đình đã động viên, giúp đỡ trong suốt
quá trình học tập nói chung và luận văn Thạc sĩ nói riêng, có lẽ nếu thiếu sự
v


0.0

Chương 0

hỗ trợ tinh thần từ gia đình thì luận văn này khó có thể hoàn thành được.

vi



Chương 1
Giới thiệu luận văn
1.1

Lý do chọn đề tài

Tính toán song song đang là giải pháp cho các yêu cầu liên quan đến sức
mạnh tính toán và kích thước bộ nhớ. Phương pháp chuẩn để tăng hiệu năng
là kết hợp các máy tính hoặc các bộ vi xử lý, để chúng kết hợp với nhau cùng
thực thi một chương trình. Hướng tiếp cận này giảm thời gian hoàn thành
công việc bằng cách tăng cả sức mạnh tính toán lẫn kích thước bộ nhớ. Trước
đây, các chương trình song song được viết ra chủ yếu để giải quyết các bài
toán khoa học trong các viện nghiên cứu. Máy tính song song hiếm khi được
sử dụng cho các ứng dụng phổ thông, chỉ giới hạn cho các bài toán tính toán
khoa học cần bộ nhớ lớn và sức mạnh tính toán.
Vài năm trở lại đây, phạm vi của xử lí song song chuyển dần sang các
lĩnh vực mới như Khai phá dữ liệu, tìm kiếm trên web. Hơn nữa, việc tạo ra
các hệ thống song song phân cụm từ các máy PC trở nên dễ ràng hơn nhờ
các phần mềm trung gian đang phát triển mạnh mẽ. Các công ty lớn như
Google cũng thực thi các công việc tính toán lớn trên các kiến trúc phân
cụm này [4]. Hơn nữa, hiện nay các bộ vi xử lý đa lõi xuất hiện khắp nơi,
sự nổi lên của các kiến trúc mới này khiến cho lập trình song song trở thành

1


1.1


Chương 1

vấn đề tất yếu. Sẽ không lâu nữa, ngành công nghiệp tính toán sẽ phải đối
mặt với vấn đề viết các chương trình song song hiệu quả và đúng đắn.
Lập trình song song trở thành một thách thức. Không giống như chương
trình tuần tự, chương trình song song được thực thi trên P bộ vi xử lý; điều
này là gánh nặng cho lập trình viên để tận dụng hết các bộ vi xử lý một
cách hiệu quả. Nói chung, lập trình viên cần viết thêm các đoạn mã để tiến
hành các tác vụ sau: phân rã miền của bài toán thành P miền con, xác định
P tác vụ để làm việc với các miền này, sau đó đồng bộ các tác vụ. Mặc dù,
đây là các khái niệm đơn giản, xong thậm chí những lập trình viên chuyên
nghiệp cũng cần những nỗ lực thực sự để hoàn thành chúng.
Đối với những lập trình viên đã quen với lập trình tuần tự thì việc viết
các chương trình song song cũng quan trọng không kém so với việc giảm
thời gian thực thi của chương trình. Họ muốn xây dựng các ứng dụng nhanh
chóng và dễ dàng nhất có thể. Điều này thúc đẩy phát triển các cơ chế lập
trình song song mới, cho phép lập trình viên lập trình dễ dàng như đang viết
chương trình tuần tự, hơn nữa chương trình đó phải chạy nhanh nhất có thể
trên các máy tính song song.
Có một số hướng tiếp cận để phát triển các công cụ lập trình song song
mức cao. Các công cụ này dừng ở mức trừu tượng để che giấu sự thực thi
bên dưới và giảm thiểu tính phức tạp, do vậy người dùng sẽ nhanh chóng
xây dựng các chương trình song song. Các công cụ này thể hiện dưới dạng
là một Ngôn ngữ lập trình bậc cao mới hoặc thư viện lập trình song song
phức tạp như MPI hay PVM, và do vậy lập trình viên không tốn quá nhiều
thời gian để nghiên cứu nhằm lấp khoảng trống kiến thức giữa lập trình song
song và lập trình tuần tự. Tư tưởng sẽ là cố gắng làm cho lập trình viên có
thể viết các chương trình song song như thể đang viết chương trình tuần tự,
ngoại trừ một số hàm đặc biệt cần biên dịch cả song song và tuần tự. Khi
chương trình chạy trên máy tính song song, trình biên dịch song song sẽ tự

động được sử dụng.
Lập trình song song theo cấu trúc khung (hay còn gọi là lập trình song
2


1.1

Chương 1

song có cấu trúc) [3]-[11] đã nổi lên là một cách tiếp cận đầy hứa hẹn để
đạt được mục đích nêu trên. Trong lập trình song song theo cấu trúc khung,
lập trình viên xây dựng chương trình song song dựa trên các thành phần đã
tạo sẵn (Ví dụ: các cấu trúc khung, các mẫu có sẵn), các thành phần sẵn
có này làm cho chương trình thực thi hiệu quả và làm cho tiến trình song
song hóa trở lên đơn giản. Có rất nhiều định nghĩa về cấu trúc khung, nhưng
nhìn chung nó là các khuôn mẫu cho tính toán song song, và các tương tác,
nó được đóng gói thành các khối như framework, hay template, hay thậm
chí là một cấu trúc khung khác. Các chương trình song song theo kiểu cấu
trúc khung rất dễ hiểu thậm chí với những người lập trình song song ít kinh
nghiệm, bởi vì mã nguồn của chương trình nhìn rất giống với một chương
trình tuần tự có một luồng thực thi duy nhất.
Tuy nhiên, chỉ có một vài ứng dụng thực sự được phát triển bằng các cấu
trúc khung song song. Có bốn lý do chính lý giải cho điều này. Thứ nhất,
giống như các design pattern trong kỹ nghệ phần mềm, các cấu trúc khung
song song được đề cập đến theo cách khá đặc biệt mà chủ yếu dựa trên các
miền ứng dụng. Không có một nguyên lý rõ ràng trong việc thiết kế cấu trúc
khung, ví dụ như làm thế nào để tạo các cấu trúc khung mới hoặc kết hợp
tập các cấu trúc khung khác nhau cho các mục đích khác nhau. Thứ hai,
bởi vì lập trình song song dựa vào tập cố định các cấu trúc khung song song
thô sơ để đặc tả giải thuật song song, nên người lập trình thường khó khăn

khi muốn chọn đúng và sau đó tích hợp với nhau để phát triển các chương
trình song song hiệu quả. Trong đa số trường hợp, lý do tại sao người lập
trình cảm thấy miễn cưỡng khi dùng các cấu trúc khung, chỉ đơn giản là vì
họ không chắc chắn liệu các cấu trúc khung đã có có đủ mạnh để giải quyết
vấn đề của họ hay không, và do vậy họ rất dễ từ bỏ. Thứ ba, vì giải thuật
song song được đặc tả bằng các cấu trúc khung, nên tồn tại rất nhiều chi phí
thừa. Có thể lý giải điều này bằng một trường hợp đơn giản, đó bởi vì có
nhiều cấu trúc dữ liệu trung gian không cần thiết được truyền giữa các cấu
trúc khung. Cuối cùng, vì hầu hết các hệ thống cấu trúc khung được định
nghĩa dựa trên một số ngôn ngữ mới hoặc đòi hỏi mở rộng ngôn ngữ hiện tại
3


1.3

Chương 1

bằng các cú pháp mới, và do vậy, dưới góc nhìn của lập trình viên, nó không
hoàn toàn giấu đi được tất cả chi tiết ở mức thấp của lập trình song song.
Người lập trình tuần tự (người lập trình song song ít kinh nghiệm) thường
cảm thấy không thoải mái khi sử dụng chúng.
Từ những lý do trên dẫn đến đề tài đi sâu tìm hiểu về cách thiết kế, xây
dựng cấu trúc khung cho các hệ thống lập trình song song đa lõi.

1.2

Mục đích nghiên cứu của luận văn

Luận văn có mục đích nghiên cứu sau:
• Nghiên cứu hướng tiếp cận lập trình song song theo cấu trúc khung

• Nghiên cứu Lý thuyết tính toán trên giải thuật nhằm áp dụng xây dựng
cấu trúc khung
• Xây dựng cấu trúc khung cho cấu trúc dữ liệu HTA
Đối tượng nghiên cứu gồm:
• Hệ thống tính toán song song
• Ngôn ngữ lập trình song song
• Đại số cho lập trình
Phạm vi nghiên cứu của luận văn giới hạn trong các cấu trúc dữ liệu song
song, thiết kế chương trình dựa trên các lý thuyết về Đại số cho lập trình.

1.3

Luận điểm cơ bản và đóng góp mới

Xây dựng nên các chương trình song song là công việc phức tạp, người lập
trình cần phải nắm rõ sự điều phối công việc giữa các tiến trình, chính điều
4


1.4

Chương 1

này là cho lập trình song song khó đi vào thực tế. Từ luận điểm này luận
văn muốn tìm hiểu về phương pháp để xây dựng nhanh chóng và đơn giản
các chương trình song song.
Luận điểm cơ bản thứ hai trong luận văn cần phải nói đến đó là việc sử
dụng lý thuyết Đại số cho lập trình để xây dựng chương trình. Dựa trên lý
thuyết này, việc định nghĩa ra các cấu trúc đại số mới là rất thuận tiện, đồng
thời việc suy luận, tính toán trên các cấu trúc đại số là chặt chẽ dựa trên

các định lý, bổ đề và các luật đại số.
Đóng góp mới của đề tài là đã đưa ra được định nghĩa đại số cho cấu
trúc dữ liệu HTA, homomorphism và các cấu trúc khung trên cấu trúc dữ
liệu này.

1.4

Cấu trúc luận văn

Luận văn được chia thành 5 chương, tổ chức như sau:
• Chương một đưa các các vấn đề cơ bản có liên quan đến luận văn.
• Chương hai trình bày cơ bản về hướng tiếp cận lập trình song song
theo cấu trúc khung, mô hình và tư tưởng lập trình theo cấu trúc khung
được đưa ra trong chương này. Chương này cũng trình bày tóm tắt 4
cấu trúc khung thường hay được sử dụng, đó là: cấu trúc khung chiatrị, cấu trúc khung kết hợp lặp, cấu trúc khung cluster, và cấu trúc
khung hàng đợi công việc.
• Chương ba trình bày về Lý thuyết tính toán trên giải thuật, đây không
phải là một lý thuyết mới, tuy nhiên việc áp dụng nó để xây dựng cấu
trúc khung lại là một hướng tiếp cận mới. Sự kết hợp này cho phép
dễ dàng xây dựng nên các cấu trúc khung một cách có hệ thống. Tuy
nhiên theo lý thuyết này, các cấu trúc khung phải được xây dựng trên

5


1.4

Chương 1
các cấu trúc dữ liệu cơ bản. Chương này cũng trình bày thiết kế của
các cấu trúc khung cho hai kiểu dữ liệu là Danh sách và Ma trận.

• Chương bốn trình bày về cấu trúc dữ liệu HTA mà tác giả đã xây
dựng dựa trên sự kết hợp của lập trình song song theo cấu trúc khung
và Lý thuyết tính toán trên giải thuật.
• Chương năm nêu kết luận và hướng phát triển của luận văn.

6


Chương 2
Lập trình song song theo kiểu
cấu trúc khung
Chương này giới thiệu về Lập trình song song theo kiểu cấu trúc khung. Các
khái niệm cơ bản về hướng tiếp cận lập trình có cấu trúc được đưa ra. Cuối
chương là một số các cấu trúc khung phổ biến đã được sử dụng trong lập
trình.

2.1

Đặt vấn đề

Ý tưởng của hệ thống lập trình theo cấu trúc khung dựa trên hai vấn đề sau.
Thứ nhất, trong ngữ cảnh lập trình tuần tự, những thách thức đặt ra để
tạo nên các giải thuật tốt cần được liên tục nghiên cứu mở rộng. Khi kinh
nghiệm lập trình nhiều hơn, lại nảy sinh việc chọn lựa kỹ thuật thực thi cho
giải thuật, một kỹ thuật có thể phù hợp với một số vấn đề nhưng cũng có thể
không tốt với các vấn đề khác. Ví dụ, ta thường quen với các khái niệm lập
trình như: “Chia và trị”, “Quy hoạch động”. Khi tìm ra một vấn đề mới, ta
thường cố gắng hình thành nên giải pháp theo một trong các kiểu trên. Do
chúng ta đã biết cách thực thi cấu trúc tính toán cơ bản của từng kỹ thuật,
7



2.1

Chương 2

nên chỉ cần đưa ra những chi tiết cần thiết cho chương trình mới.
Dựa vào ý tưởng trên, có thể đưa ra một hệ thống theo phương pháp như
sau: Ban đầu, cần xác định tập các kỹ thuật giống nhau, mỗi kỹ thuật có
cấu trúc tính toán có thể thực thi song song được. Nếu các cấu trúc cơ bản
có thể song song hóa được thì các thể hiện của cấu trúc đó cũng có thể có
khả năng song song hóa. Thay vì tạo ra các cấu trúc lập trình song song mới,
ta cố gắng nhúng các kỹ thuật song song trong các cấu trúc cú pháp của mô
hình lập trình, và do đó người dùng sẽ dùng nó như là cấu trúc chính trong
chương trình của họ. Hơn nữa, ta mong muốn dưới góc nhìn của người dùng
thì các cấu trúc này là không song song.
Tư tưởng của vấn đề thứ hai là làm sao để giải quyết vấn đề thứ nhất
theo cách mạch lạc và ở mức cao. Đây chính là khái niệm “Hàm bậc cao”.
“Hàm bậc cao” thể hiện sức mạnh của các ngôn ngữ lập trình hàm. Dưới đây
đưa ra giải thích ngắn gọn về khái niệm “Hàm bậc cao”.
Các hàm đơn giản nhận đối số đầu vào là một số kiểu dữ liệu nào đó, dữ
liệu trả về sẽ có một kiểu dữ liệu nào đó. Ví dụ, hàm bình phương của một
số nguyên được định nghĩa như sau:
square x = x ∗ x
Hàm trên nhận đối số vào là một số nguyên và trả về kết quả là một số
nguyên. Kiểu của hàm này được mô tả như sau:
square : int → int
Một số hàm có thể hoạt động dựa trên các dữ liệu gồm nhiều hơn một kiểu
dữ liệu, bởi các hoạt động mà hàm đó tiến hành không quan tâm đến chi
tiết đối số, mà chỉ là cấu trúc của đối số đó. Ví dụ điển hình cho hàm kiểu

đó là hàm “head ”, hàm này có đối số đầu vào là một danh sách các mục có
kiểu dữ liệu nào đó, hàm sẽ trả về mục dữ liệu đầu tiên trong danh sách. Rõ
ràng ta thấy kiểu dữ liệu của các mục dữ liệu là không ảnh hưởng đối với
hàm, và các hàm như vậy được gọi là có tính chất đa hình. Kiểu của hàm
8


2.1

Chương 2

được biểu thị dùng các biểu tượng giả để biểu diễn các kiểu dữ liệu tùy ý.
Như vậy, “head” có kiểu là:
head : [a] → a
trong đó, dấu ngoặc vuông biểu thị cho “danh sách” và “a” biểu thị cho bất
kỳ kiểu dữ liệu nào.
Hàm bậc cao phức tạp hơn một chút. Thay vì đầu vào và đầu ra là các
dữ liệu đơn giản, thì hàm bậc cao nhận đối số đầu vào là một hàm khác và
trả về một hàm mới. Hàm kết quả là sự kết hợp có cấu trúc giữa các hàm
đối số và một số hàm khác có thể có. Có lẽ hàm bậc cao đơn giản và hay
dùng nhất đó là hàm “map”. Đối số đầu vào của hàm map là hàm có kiểu:
f :a→b
a và b có thể là các kiểu bất kỳ, có thể là các kiểu giống nhau. Kết quả sau
khi áp dụng hàm map với một hàm f sẽ trả về hàm “map f ” có kiểu:
( map f ) : [a] → [b]
Hay nói cách khác, hàm trên có đối số là một danh sách các phần tử có kiểu
là “a” và trả về danh sách các phần tử có kiểu là “b”. Ảnh hưởng của hàm
“map f ” là áp dụng hàm f trên mọi phần tử trong danh sách đối số, sau
đó đặt kết quả vào vị trí tương ứng trong danh sách kết quả. Ví dụ, “map
square” có kiểu:

(map square) : [int] → [int]
sẽ trả về danh sách các số bình phương của các số nguyên trong danh sách
đối số. Điểm quan trọng ở đây là ta có thể coi “map” như một hàm của chính
hàm đó, với kiểu:
(map) : (a → b) → ([a] → [b])
Hàm bậc cao chính xác là loại đối tượng mà ta cần tìm kiếm để thực
thi khái niệm gọi là “Các kỹ thuật tổng quát trên giải thuật”. Chúng không
quan tâm đến chi tiết ở mức thấp của các giải thuật cụ thể. Thay vào đó,
9


2.2

Chương 2

chúng quan tâm đến cấu trúc tính toán mức cao của toàn bộ các lớp trong
giải thuật. Các giải pháp cho các bài toán nhỏ, cụ thể có thể được thực hiện
bằng cách áp dụng các hàm đối số có thể tùy chỉnh được, nó tương ứng với
các tác vụ làm bằng tay. Do đó, ta có thể dùng hàm map kết hợp với một
số hàm đơn giản để đưa ra các kết quả khác nhau, sử dụng chúng trong cấu
trúc tổng thể là như nhau. Ví dụ, cho một hàm “uppercase” trả về các ký tự
viết in tương ứng của các ký tự thường trong đối số đầu vào:
uppercase : char → char
Ta dễ dàng sử dụng “map uppercase” để chuyển đổi danh sách các ký tự theo
một cách thống nhất:
(map uppercase) : [char] → [char]
Giải thuật mức cao là giống với giải thuật của “map uppercase”, chỉ có chi
tiết ở mức dưới là khác. Hay nói cách khác, cách dùng của “map” giống với
cấu trúc tính toán cơ bản mà ta đang nói đến, trong khi đó hàm đối số của
nó quan tâm đến bài toán cụ thể mà ta cần giải quyết một cách thủ công.


2.2

Cấu trúc giải thuật khung - Hướng tiếp
cận có cấu trúc để quản lý các tính toán
song song

Trong khi Hàm bậc cao thể hiện rất tốt trong các framework ngữ nghĩa của
ngôn ngữ lập trình hàm, thì ta có thể tưởng tượng những thứ tương tự trong
ngữ cảnh của ngôn ngữ lập trình chỉ thị/mệnh lệnh. Trong đó, Hàm bậc cao
có thể được biểu diễn như một chương trình hay một template, nó xác định
cấu trúc tổng thể của bài toán tính toán. Khoảng trống trong cấu trúc tổng
thể sẽ được lấp đầy bằng các định nghĩa về các thủ tục và khai báo cụ thể
cho bài toán. Sự thực thi cấu trúc trên sẽ càng trở nên tốt hơn trong các
10


2.2

Chương 2

ngôn ngữ cho phép truyền thủ tục như là các đối số. Do vậy, hệ thống mà
ta mong muốn đưa ra cho người dùng có thể sử dụng trong bất kỳ ngữ cảnh
nào của ngôn ngữ nền, dù là ngôn ngữ khai báo hay ngôn ngữ mệnh lệnh.
Bây giờ ta sẽ mô tả mô hình lập trình cấu trúc khung. Trong mô hình
này, người lập trình sẽ lựa chọn một hàm bậc cao trong danh sách các hàm
bậc cao chuyên biệt, hàm bậc cao đã lựa chọn chính là hàm ở mức ngoài
cùng trong chương trình. Người lập trình sau đó sẽ dùng sức mạnh của ngôn
ngữ lập trình để viết các hàm, các hàm này sẽ được dùng bởi hàm bậc cao
đã lựa chọn, và cuối dùng đưa ra kết quả của chương trình. Giới hạn của cấu

trúc chương trình đó là chương trình cần có cấu trúc ngoài cùng khớp với
các hàm bậc cao của mô hình, chương trình như vậy gọi là một chương trình
hợp lệ. Với giới hạn này, ta sẽ không phải quan tâm đến chi tiết mức thấp
của chương trình, vì nó không ảnh hưởng đến cấu trúc cơ bản của giải thuật
hay sự thực thi của chương trình. Chúng ta gọi hàm bậc cao thích hợp là
một “Cấu trúc giải thuật khung”, vì nó mô tả cấu trúc khung tính toán của
của một giải thuật mà không cần mô tả chi tiết phía dưới. Để thuận tiện, từ
nay ta sẽ gọi Cấu trúc giải thuật khung là Cấu trúc khung.
Việc xây dựng các cấu trúc khung trong môi trường thông thường không
quan tâm đến sự song song hóa là rất dễ dàng và nhanh chóng. Ta sẽ định
nghĩa các cấu trúc khung cho tất cả các lược đồ giải thuật quen thuộc, và
hỗ trợ thực thi mã nguồn một cách tối ưu cho các mã nguồn mà người dùng
viết, sau đó mã nguồn sẽ được tích hợp tự động với các cấu trúc khung. Điểm
quan trọng để có được hiệu năng song song một cách hiệu quả cho mô hình
trên đó là cần phải đảm bảo rằng mỗi một hàm trong số các hàm bậc cao
phải mô tả được cấu trúc tính toán mà đối với cấu trúc đó ta luôn tìm được
sự thực thi song song hiệu quả bất kể chi tiết cụ thể của chương trình thế
nào. Đó chính là các kỹ thuật cho giải thuật song song hiệu quả. Tất nhiên,
đối với lập trình viên thì các đặc tả thực sự của mỗi cấu trúc khung không
nhất thiết phải là song song một cách rõ ràng.
Nếu chúng ta cố gắng tránh rơi vào cái bẫy trong việc thực thi ngôn ngữ

11


2.2

Chương 2

tổng quát nào đó một cách tự động, thì có vẻ như ta đã tự giới hạn mình

trong việc khám phá tính kế thừa sự song song hóa trong cấu trúc cơ bản
của mỗi cấu trúc khung. Các hàm đặc tả bài toán ở mức thấp có thể có khả
năng song song hoặc không, nhưng ta nên bỏ qua chúng bởi vì ta càng cố
gắng phân tích sâu hơn sẽ càng rơi vào bẫy về tính tổng thể. Tác vụ thực thi
là để song song hóa sự phân tán dữ liệu cũng như các thao tác chỉnh sửa dữ
liệu ở cấu trúc mức cao nhất, còn các hàm khác được thực thi toàn bộ trên
từng bộ vi xử lý riêng lẻ, mã nguồn của người dùng sẽ đặt trực tiếp vào cấu
trúc thực thi tuần tự tổng thể. Hướng tiếp cận này có thêm hai ưu điểm.
Việc lựa chọn ngôn ngữ lập trình dùng để mô tả chi tiết bài toán chỉ bị giới
hạn bởi tính sẵn sàng của các trình biên dịch cho các bộ vi xử lý tuần tự
của các máy song song. Thứ hai, ta luôn có được điểm lợi từ các trình biên
dịch tốt nhất, bởi vì các mã được sinh ra không đòi hỏi phải tương tác với
cấu trúc song song.
Tổng kết lại, người lập trình nhìn các cấu trúc khung như là hàm bậc
cao (hoặc các template trong trường hợp ngôn ngữ nền là ngôn ngữ mệnh
lệnh), cấu trúc khung là một trong số các công cụ trên giải thuật mà từ đó
chương trình cụ thể sẽ được cấu thành. Trong khi đó, đối với người thực thi
hệ thống, mỗi một cấu trúc khung là một cấu trúc tính toán nói chung, trong
đó các khung song song tương ứng và hiệu quả cần được định nghĩa. Đúng
như các ngôn ngữ thông thường cần trình biên dịch khác nhau cho các máy
khác nhau, thì mỗi cấu trúc khung cũng sẽ đòi hỏi sự thực thi khác nhau
đối với mỗi một máy tính song song. Cũng như các trình thông dịch thông
thường, sự khác nhau này là trong suốt đối với lập trình viên, đối với lập
trình viên thì họ chỉ thấy một framework độc lập giống nhau trên các máy.
Tiếp đến ta sẽ xem xét đến vấn đề phân hoạch và phân tán dữ liệu. Chú
ý quan trọng ở đây là sự phân hoạch song song được đã được ngầm ý trong
cấu trúc của mỗi cấu trúc khung. Do đó khi lựa chọn cấu trúc khung nào đó,
người dùng cần lựa chọn cách phân hoạch song song. Tương tự như vậy, tác
vụ phân tán chính là vấn đề thực thi một trong số các lựa chọn phân hoạch
đã có trên từng cấu trúc khung. Vì các cấu trúc này được thực thi chỉ một

12


2.2

Chương 2

lần đối với mỗi tôpô phần cứng, nên chúng có thể được chỉnh sửa bằng tay
để tối ưu hóa hiệu năng. Tất cả các chương trình được viết với cùng cấu trúc
khung sẽ dùng cùng một cấu trúc thực thi đã định nghĩa trước với các kịch
bản phân tán sẵn có. Do vậy, trong quá trình lựa chọn cấu trúc khung, người
lập trình chỉ cần lựa chọn kế hoạch phân tán liên quan đến nó.
Ta có thể tưởng tượng một phiên tương tác của một môi trường lập trình
tạo bởi mô hình ở trên. Trong lúc kích hoạt hệ thống, người lập trình có thể
lựa chọn cấu trúc khung từ một danh sách các cấu trúc khung sẵn có. Giống
như đối với ngôn ngữ lập trình thông thường, các chi tiết nhỏ và các ví dụ
của cấu trúc khung sẽ được mô tả trong tài liệu hướng dẫn người dùng tương
ứng. Cấu trúc khung cho bài toán được lựa chọn một cách thủ công. Tương
tự, người dùng sẽ lựa chọn ngôn ngữ nền để sử dụng trong việc đặc tả các
thủ tục cũng như cấu trúc dữ liệu bổ sung cho cấu trúc khung đã chọn. Hệ
thống đáp ứng lại bằng cách hiển thị một chương trình chung mô tả hoạt
động của cấu trúc khung đã lựa chọn với ngôn ngữ nền đã chọn.
Cuối cùng, hệ thống nhắc cho người dùng mô tả cấu trúc dữ liệu và các
thủ tục cần thiết để chuyển các cấu trúc khung trừu tượng thành một đặc
tả giải pháp đầy đủ. Do các mô tả đã nhất quán về mặt thuật ngữ trong cú
pháp của ngôn ngữ đã lựa chọn, nên tác vụ “lập trình” đến lúc này là đã
hoàn thành. Để khởi tạo một quá trình chạy cho chương trình, chỉ việc chỉ
định vị trí (trong hệ thống tệp tin cục bộ) của cấu trúc dữ liệu mà mô tả
thể hiện của bài toán.
Lúc này, đến lượt hệ thống. Dữ liệu và các đoạn mã đã biên dịch của

người dùng được tải đến phần cứng song song cùng với mã hệ thống đã biên
dịch sẵn cần thiết cho việc thực thi cấu trúc khung đã lựa chọn. Phần cứng
sẽ thực thi cấu trúc khung, gọi các định tuyến tương ứng của người dùng và
trả về cho hệ thống một thể hiện cấu trúc dữ liệu tương ứng. Cơ chế thực
thi tiến trình này là hoàn toàn ẩn đối với người dùng.
Như vậy, trong phần này ta đã bước đầu nhắc đến thế nào là cấu trúc
khung, mô hình lập trình theo cấu trúc khung. Các mục tiếp theo của chương
13


2.3

Chương 2

này sẽ giới thiệu một số cấu trúc khung hay sử dụng.

2.3

Cấu trúc khung chia-trị

2.3.1

Đặt vấn đề

Cấu trúc khung đầu tiên ta xem xét là một biến thể của kỹ thuật “Chia và
trị”. Nói chung, “Chia và trị” có thể áp dụng khi lời giải của bài toán được
định nghĩa một cách đệ quy bởi các hàm trong tập các thể hiện giống nhau
của bài toán sinh ra từ mô tả của thể hiện gốc. Đệ quy sẽ không được dùng
nếu như thể hiện của bài toán có cảm giác không chia được, trong trường
hợp này cần một giải pháp trực tiếp bằng cách sử dụng một số phương thức

đơn giản.
Rõ ràng, các giải thuật chia và trị có tiềm năng tốt để tính toán song
song. Dễ thấy rằng, một cách đệ quy thì các bài toán con có thể được tính
toán đồng thời nếu như tất cả bộ vi xử lý đã sẵn sàng. Quá trình thực thi
của giải thuật chia và trị sẽ đếm các bài toán con được sinh ra để ước tính
ra cây tiến trình. Cây tiến trình là luôn luôn thay đổi trong quá trình thực
thi. Khó khăn ở đây là phải đảm bảo quá trình ánh xạ cây tiến trình lên các
máy thật là hiệu quả nhất có thể. Tác vụ song song hóa lược đồ chia và trị
trong trường hợp xấu nhất được đề cập trong các tài liệu [12],[6],[10].

2.3.2

Hướng tiếp cận ZAPP

ZAPP là một máy cây ảo, nó ánh xạ động một cây tiến trình lên một mạng
gồm số lượng cố định các cặp Vi xử lý-Bộ nhớ, các cặp này là các máy không
chia sẻ bộ nhớ với nhau. “Ăn cắp” là nguyên lý cơ bản được dùng trong quá
trình ánh xạ tiến trình lên các bộ vi xử lý. Theo đó, một bộ vi xử lý sẽ lấy
về tiến trình hoặc công việc từ các bộ vi xử lý bên cạnh của nó. Quá trình
phân tán bài toán do đó được điều khiển theo yêu cầu, tức là một bộ vi xử
14


2.3

Chương 2

lý sẽ cố gắng giải quyết một bài toán và toàn bộ bài toán con của nó, trừ khi
các bài toán này bị lấy đi bởi một bộ vi xử lý nào đó. Nguyên lý “Ăn cắp”
tuân theo luật rất đơn giản, đó là, quá trình “Ăn cắp” có thể được lặp lại.

Do đó, một bài toán luôn được giải quyết trên một bộ vi xử lý mà về mặt
vật lý nó nằm kề với bộ vi xử lý chứa bài toán cha, như vậy sẽ giảm thiểu
được trễ truyền thông. Hay nói cách khác, luật ăn cắp nghĩa là cách phân
bố toàn bộ bài toán đến các máy tính thì chậm hơn so với cách giành giật
bài toán. Những thí nghiệm ban đầu cho thấy kỹ thuật này thành công nhất
khi số lượng bài toán con về thực chất là lớn hơn số lượng bộ vi xử lý.
Ta xem xét một dạng đơn giản của ZAPP, đó là hàm bậc cao “DC ” được
định nghĩa như sau:
DC indivisible split join f = F
where F P = f P, if indivisible P
= join (map F (split P )), otherwise
Do vậy, nếu các thể hiện của bài toán có kiểu “prob” và các giải pháp có
kiểu “sol”, thì người lập trình cần đưa ra chương trình cụ thể sử dụng hàm
bậc cao bằng cách cung cấp định nghĩa sau:
indivisible : prob → boolean
f : prob → sol
split : prob → [prob]
join : [prob] → prob
trong đó, “indivisible” là hàm kiểm tra thể hiện của bài toán và quyết
định xem bài toán được giải quyết theo cách đệ quy hay không, “f ” là hàm
để xử lý với trường hợp cơ bản với các thể hiện không thể chia được nữa,
“split” là hàm phân rã bài toán thành các bài toán con và “join” là hàm mô
tả cách kết hợp kết quả từ các bài toán con để giải quyết bài toán gốc. Hàm

15


2.3

Chương 2


bậc cao DC có kiểu:
DC :(prob → bool) → (prob → [prob]) → ([sol] → sol)
→ (prob → sol) → (prob → sol)
Chú ý quan trọng trong phiên bản chia và trị này là không tạo ra giả thiết
nào về dạng của cây tiến trình. Cụ thể, số lượng các bài toán con sinh ra
dựa trên hàm “split” có thể biến đổi giữa các nút cũng như có thể thay đổi
độ sâu của các cây con khác nhau. Vì cấu trúc của cây tiến trình thay đổi
động, nên không thể gán trước mô hình phân tán tiến trình lên bộ vi xử lý.
Hướng tiếp cận ZAPP “ăn cắp” nhằm mục đích cho phép sự phân tán bài
toán được xây dựng một cách tự nhiên, trong đó công việc được sinh ra ở các
nhánh “nặng” sẽ được phân bố qua mạng đến các bộ vi xử lý mà đã hoàn
thành xong nhánh “nhẹ”.

2.3.3

Hướng tiếp cận FDDC

Hướng tiếp cận ZAPP phù hợp với mô tả của ta về “cấu trúc giải thuật
khung”. Đặc tả của nó là không song song giống như hàm bậc cao độc lập
với bài toán, còn sự thực thi thì che giấu đi tính song song. Tuy nhiên, trong
khi các kết quả ghi nhận là tốt, nhưng bản chất không dự đoán trước được
của cây tiến trình lại là một cái gì đó rất lỏng lẻo hơn là việc định nghĩa
trước kiểu phân tán. Do đó, ta sẽ đưa ra một dạng giới hạn hơn của cấu trúc
khung chia-trị, trong đó người dùng sẽ tham gia nhiều hơn vào quá trình
phân tán bài toán, cung cấp mức độ mềm dẻo nào đó ở tầng của người lập
trình. Hướng tiếp cận này rõ ràng là cùng quan điểm với những động lực đã
thảo luận trong phần đặt vấn đề của chương này.
Giới hạn đưa ra ở đây là đối với bất kỳ bài toán chia-trị nào thì mức độ
của các nút không phải nút lá là một số cố định và được xác định trước khi

quá trình thực thi bắt đầu. Hay nói cách khác, với bất kỳ bài toán nào mà
không giải quyết trực tiếp được thì cần phải sinh ra số lượng không đổi k
bài toán con trong quá trình gọi hàm “split”. Cấu trúc khung này được gọi
16


2.4

Chương 2

là Cấu trúc khung có mức cố định, viết tắt là FDDC. Trong cấu trúc khung
này, người dùng phải chỉ định giá trị k, chỉ định các hàm “indivisible”, “f”,
“joink ”, “splitk ”, trong đó các hàm split và join có phụ thuộc vào giá trị k.
Giải thuật FDDC đơn giản và chung nhất là có giá trị k = 2 . Ví dụ điển
hình là giải thuật “mergesort” để sắp xếp một danh sách. Trong trường hợp
này, danh sách không thể chia được là danh sách có số phần tử là 0 hoặc 1,
hàm “f” trong trường hợp cơ bản là hàm chỉ đơn giản trả về đối số của nó,
hàm “split2 ” chia danh sách thành hai danh sách con một cách đệ quy.

2.4
2.4.1

Cấu trúc khung kết hợp lặp
Đặt vấn đề

Rất nhiều bài toán được giải quyết bằng giải thuật áp dụng cấu trúc lên tập
các đối tượng khởi tạo. Thông thường, thể hiện của bài toán như vậy được
mô tả bằng tập các đối tượng đồng nhất, cùng với các chi tiết trong cấu trúc
bên trong của nó và mối quan hệ tồn tại giữa chúng. Cho trước một luật để
kết hợp hai đối tượng, và độ đo giá trị của sự kết hợp, giải thuật sẽ lặp qua

một vòng lặp trong đó mỗi đối tượng được kết hợp với đối tượng khác phù
hợp nhất trong số các đối tượng còn lại. Vòng lặp kết thúc khi tất cả các đối
tượng đã được kết hợp lại thành một, hoặc không còn khả năng kết hợp nào
nữa. Các giải thuật kiểu này thường được phân vào lớp các giải thuật “tham
lam”, bởi vì tính cục bộ của nó hơn là bản chất tối ưu toàn bộ của việc ra
quyết định. Chính sách này có thể có hoặc không đưa đến kết quả tối ưu
toàn bộ, nó còn phụ thuộc vào các tính chất của bài toán cụ thể.
Xét một giải thuật ngắn gọn, đó là giải thuật của Sollin [14] để tìm cây
nhỏ nhất trong một đồ thị vô hướng. Các đối tượng mô tả một thể hiện của
bài toán chính là tập tất cả các cây con của đồ trị đã xét. Ban đầu, mỗi đỉnh
sẽ là một cây con có một đỉnh. Hai đối tượng được kết hợp với nhau bằng
cách tìm cạnh ngắn nhất kết nối hai đối tượng với nhau, chi phí cho một sự
17


2.4

Chương 2

kết hợp như vậy chính là giá trị của cạnh này (hoặc là lớn vô cùng nếu không
tồn tại cạnh nào thỏa mãn). Phần tốt nhất của một đối tượng là phần mà
được kết hợp ở chi phí thấp nhất, ví dụ, cây con còn lại có thể được kết hợp
ở chi phí thấp nhất.
Tại mỗi vòng lặp, đối với mỗi cây con còn lại, giải thuật tìm cạnh có chi
phí thấp nhất mà nó kết nối cây con với một số cây con khác. Các cây này
được thay thế bởi một cây mới biểu diễn các cây cũ được kết nối bằng cạnh
ngắn nhất. Tiến trình này lặp đi lặp lại cho đến khi chỉ còn lại một cây con
duy nhất (Cây có chi phí nhỏ nhất trong đồ thị gốc), hoặc cho đến khi các
cây con còn lại không có cạnh nào giữa chúng. Trong trường hợp này, không
có sự kết hợp được tìm thấy thêm nữa và các cây đó sẽ biểu diễn một rừng

của đồ thị gốc không kết nối.
Cấu trúc khung “Kết hợp lặp”, hay còn gọi là IC (iterative combination)
mô hình hóa kiểu giải pháp như trên. Đặc tả trừu tượng của nó và sự thực
thi song song có thể trên hệ thống song song sẽ được mô tả trong chương
này.

2.4.2

Đặc tả cấu trúc khung kết hợp lặp

Câu hỏi đầu tiên được đặt ra ở đây là Cấu trúc khung kết hợp lặp sẽ được
đặc tả theo kiểu chỉ thị sử dụng “template” của lập trình tuần tự, hay sử
dụng theo kiểu khai báo như hàm bậc cao. Ở đây ta sẽ xem xét cả hai hướng
tiếp cận. Ta sẽ bắt đầu với hướng tiếp cận lỏng lẻo hơn - hướng tiếp cận đặc
tả theo kiểu chỉ thị. Đối với lập trình viên theo ngôn ngữ chỉ thị, cấu trúc
khung IC có thể được thực thi như đoạn giả mã trong hình 2.1, trong đó S
biểu diễn tập các đối tượng đồng nhất là các đối tượng mô tả thể hiện của
bài toán.
Để chi tiết hóa cấu trúc khung cho một bài toán cụ thể, người dùng phải
cung cấp đặc tả về kiểu của một đối tượng, chi tiết liên quan đến thủ tục để

18


×