Thuật toán song song được định nghĩa là một tập các tiến trình hoặc các tác vụ có thể thực hiện đồng thời và có thể trao đổi dữ liệu với nhau để kết hợp cùng giải một bài toán. Đây cũng chính là nơi áp dụng các nguyên lí sáng tạo. Sau đây ta sẽ xem xét các nguyên lí trong thiết kế cụ thể.
2.2.1 Nguyên lí chia để trị
Tinh thần chia để trị luôn là một trong những biện pháp thông dụng nhất để giải quyết vấn đề. Đây cũng là tinh thần của nguyên lí phân nhỏ. Bằng cách chia nhỏ công việc thành các phần con độc lập tương đối, ta có thể giải quyết đồng thời từng vấn để nhỏ, nhờ đó tăng hiệu năng hệ thống.
Ví dụ : Bài toán tính tổng A[1:n], ta thiết kế thuật toán song song có độ
phức tạp thời gian O(logn) với O(n) bộ xử lý. Thuật toán chưa tối ưu. Sử dụng việc phân chia dữ liệu ta sẽ có thuật toán với độ phức tạp thời gian O(logn) với O(n/logn) bộ xử lý.
+ Phân các phần tử của mảng vào n/logn nhóm; mỗi nhóm chứa logn
phần tử
k = logn và r = n/logn ; rk = n = 2k
Nhóm 1 : A1 A2 ……..Alogn
Nhóm 2 : Alogn + 1 ……A2logn r = n/logn nhóm ………
+ Phân mỗi nhóm cho một bộ xử lý => n/logn bộ xử lý
+ Thời gian cộng trên mỗi bộ xử lý O(logn), cất vào Bi ta thu được B1, B2, …., Bn/logn. Sau đó sử dụng thuật toán trong mục 1 ta đi tính tổng
của nó với thời gian O(log(n/logn)) ≡ O(logn) sử dụng O(n/logn) bộ xử lý.
Thuật toán tính tổng tối ưu
Đầu vào : mảng A[1:n] Đầu ra : tổng -> Sum Begin
1. For i = 1 to n/logn dopar
i. Sử dụng thuật toán tuần tự để tính tổng A(i-1)logn+1…..Ailogn và cất vào biến Bi
2. EndPar
3. Tính tổng B1, B2, …., Bn/logn => Sum End
2.2.2 Nguyên lí lập lịch
Tìm cách giảm tối thiểu các bộ xử lí trong thuật toán mà không làm tăng thời gian tính toán. Nói chung, khi số bộ xử lí giảm thời gian thực hiện của chương trình có thể tăng và có thể tăng lên một hằng số nào đó nhưng xét theo độ phức tạp của thuật toán thì vẫn không thay đổi.
Ví dụ : Xem xét bài toán tính tổng của N số (n1, n2, ……., nN), trong đó N là lũy thừa của 2. Giả sử dữ liệu nằm trên các lá của cây nhị phân có thể được thực hiện tính toán theo cách sau. N/2 phần tử xử lý (Processing Elements - PE) được giao nhiệm vụ tính toán tổng các cặp dữ liệu, ví dụ (n1, n2), (n3,
n4), …, (nN-1, nN). Kết quả này có thể được thực hiện trong một bước tính toán. Tiếp theo, N/4 phần tử xử lý thực hiện cùng công việc trên N/4 cặp dữ liệu, và v..v. Rõ ràng các tính toán tiến hành từ lá tới gốc và toàn bộ quá trình tính toán sẽ kết thúc khi mà phần tử xử lý tại gốc thực hiện xong tính toán của nó.
Thuật toán Sum
Đầu vào : mảng A(1..n), n = 2i Đầu ra : tổng lưu tại A(1) Begin
2. p = n/2
3. While p > 0 do
a. For i = 1 to p dopar
i. A(i) = A(2i-1) + A(2i) b. EndPar
c. p = p/2 4. EndWhile End
2.2.3 Nguyên lí đường ống
Nguyên lí này được áp dụng trong trường hợp ta muốn thực hiện một dãy các thao tác theo trình tự {P1, P2,…, Pn} trong đó một số bước của Pi+1 có thể thực hiên trước khi Pi kết thúc.
2.2.4 Nguyên lí phát triển bởi nhân đôi
Phương pháp phát triển bởi nhân đôi có thể được nhìn theo một cách khác. Tại mỗi bước, mỗi phần tử xử lý nhân đôi số phần tử tính toán. Vì thế
“phát triển” thu được bởi nhân đôi số lượng dữ liệu tại mỗi bước. Tất nhiên, có các cách khác nhau sử dụng kĩ thuật này, thậm chí đối với các bài toán không kết hợp với cấu trúc cây nhị phân. Sau đây là một vài ví dụ: Xem xét bài toán xếp hạng danh sách (list-ranking) : Cho một danh sách liên kết có N phần tử được lưu trong mảng A[1:N], hãy tính toán hạng của mỗi phần tử. Hạng của mỗi phần tử trong danh sách là khoảng cách từ nó tới cuối danh sách. Vì thế phần tử đầu tiên có hạng là N và phần tử cuối cùng có hạng là 1. Để giải bài toán này ta sử dụng kĩ thuật nhân đôi, chúng ta phân một bộ xử lý tới mỗi phần tử. Ban đầu mỗi bộ xử lý chỉ biết hàng xóm bên phía phải của nó trong danh sách. Tại bước đầu tiên, mỗi bộ xử lý tìm kiếm hàng xóm của hàng xóm của nó. Nghĩa là, sau bước đầu tiên mỗi bộ xử lý biết được phần tử có khoảng cách tới nó là 2. Gọi Next(i) là phần tử xa nhất nằm phía phải phần tử thứ i …Khởi tạo, next(i) là hàng xóm bên phải của i ngoại trừ phần tử cuối cùng trong danh sách thì hàng xóm bên phải của nó là Nil. Tại mỗi bước pi cập nhật next(i) tới next(next(i)) cho đến khi đạt tới cuối danh sách. Nếu tại bước k mỗi bộ xử lý biết phần tử cách nó là x thì trong bước tiếp theo mỗi bộ xử lý biết phần tử cách nó 2x. Vì thế xử lý nhân đôi đảm bảo rằng mỗi bộ xử lý sẽ đạt tới cuối danh sách trong nhiều nhất là logN bước và sẽ biết hạng của nó.
Thuật toán xếp hạng trong danh sách
Input : A(1:n), link(1:n), head Output : Rank(1:n)
Begin
1. For i = 1 to n dopar Rank(i) = 1
EndPar
2. For k = 1 to logn do
2.a For i = 1 to n dopar
if NEXT[i] <> 0
Rank(i) = Rank(i) + Rank(NEXT(i)) NEXT(i) = NEXT(NEXT(i))
endif EndPar End
KẾT LUẬN
Thông qua việc trình bày về tính toán song song và thiết kế thuật toán song song, bài viết đã cố gắng tóm lược lại những kiến thức về các phương pháp sáng tạo được truyền đạt trên lớp. Tuy vậy, bài tiểu luận vẫn còn nhiều hạn chế cũng như nhiều vấn đề chưa giải quyết được. Rất mong được sự góp ý bổ sung của thầy và các bạn để phát triển tiếp sau này.