Các phần mềm truyền thống được thiết kế theo dạng tuần tự: - Chạy trên một máy vi tính với một bộ xử lý đơn lẻ - Một vấn đề được tách thành cách chuỗi chỉ thị đơn lẻ rời rạc - Những chỉ
Trang 1TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
Thành phố Hồ Chí Minh - Tháng 07 Năm 2013
Trang 2NHẬN XÉT CỦA GIẢNG VIÊN HƯỚNG DẪN
Trang 3
NỘI DUNG
Trang 4DANH SÁCH HÌNH
DANH SÁCH BẢNG
Trang 51. GIỚI THIỆU VỀ ĐIỆN TOÁN SONG SONG
1.1 Điện toán song song là gì?
Các phần mềm truyền thống được thiết kế theo dạng tuần tự:
- Chạy trên một máy vi tính với một bộ xử lý đơn lẻ
- Một vấn đề được tách thành cách chuỗi chỉ thị đơn lẻ rời rạc
- Những chỉ thị được thực thi một cách tuần tự, hết chỉ thị này tới chỉ thịkhác
- Chỉ có một chỉ thị được thực thi tại một điểm thời gian nào đó
Hình 1: Điện toán tuần tự
Về cơ bản, điện toán song song là việc đồng thời sử dụng nhiều tài nguyêntính toán để giải quyết một vấn đề tính toán
- Chạy trên nhiều bộ vi xử lý
- Một vấn đề được tách thành những phần rời rạc có khả năng thực thiđồng thời
- Mỗi phần trên lại được tách thành một chuỗi các chỉ thị
- Các chỉ thị từ mỗi phần sẽ được thực thi đồng thời trên những bộ xử lýkhác nhau
- Một cơ chế điều khiển/hợp tác sẽ được cài đặt để kiểm soát việc thựcthi này
Trang 6Hình 2: Điện toán song song
1.2 Tại sao chọn điện toán song song
Những lý do chính điện toán song song được chọn:
- Tiết kiệm thời gian và tiền bạc: trên lý thuyết, một chương trình sửdụng nhiều tài nguyên sẽ rút ngắn được thời gian thực thi kèm với chiphí Một số chương trình càng chạy lâu thì chi phí càng nhiều: bảo trì,giám sát….Thêm nữa, những máy tính song song này hoàn toàn có thểđược xây dựng từ những thành phần rẻ tiền
- Giải quyết được những vấn đề lớn hơn: nhiều vấn đề cực lớn hoặc cực
kỳ phức tạp thì không thể được hiện thực trên máy tính đơn lẽ được,đặc biệt là máy tính với bộ nhớ ít, vi xử lý yếu Ví dụ: "GrandChallenge" (en.wikipedia.org/wiki/Grand_Challenge) là một vấn đề màyêu cầu đến tốc độ PetaFLOPS (một triệu tỷ phép tính toán số độngtrên giây) của bộ vi xử lý và lượng bộ nhớ lên đến PetaBytes (một triệu
tỷ bytes)
- Khả năng tính toán đồng thời: Một tài nguyên tính toán đơn lẽ chỉ cóthể làm một việc tại một thời điểm Nhiều tài nguyên tính toán có thểlàm nhiều việc đồng thời nhau Ví dụ, Access Grid cung cấp một hệ
Trang 7- Sử dụng tài nguyên từ xa: sử dụng các tài nguyên tính toán trên mộtmạng rộng hoặc Internet khi tài nguyên cục bộ bị khan hiếm Ví dụ:SETI@home (setiathome.berkeley.edu) có đến 1.3 triệu người dùng,3.4 triệu máy tính ở gần như mỗi quốc gia trên thế giới Nguồn:www.boincsynergy.com/stats/ (tháng 6, 2013).
- Giải quyết những hạn chế của điện toán tuần tự: việc xây dựng nhữngmáy tính nhanh hơn gặp nhiều khó khăn cả về tính vật lý cũng như tínhứng dụng Chẳng hạn đối với tốc độ chuyển tải, tốc độ của máy tínhtuần tự sẽ phụ thuộc vào việc dữ liệu di chuyển giữa các phần cứngnhanh cỡ nào, tốc độ này luôn có giới hạn tuyệt đối là tốc độ ánh sáng(30 cm/ nano giây) và giới hạn truyền tải của dây đồng (9 cm/ nanogiây) Do đó, việc tăng tốc độ này đòi hỏi sự gia tăng tương ứng củacác thành phần
1.3 Các mô hình lập trình song song
Đối với lập trình song song, có vài mô hình được sử dụng phổ biến:
a. Bộ nhớ chia sẻ
Trong mô hình này, các tác vụ chia sẻ một không gian bộ nhớ để chúng cóthể đọc và ghi một cách bất đồng bộ Việc truy cập vào bộ nhớ chia sẻ nàythường được điều khiển bởi cơ chế mutex hay semaphore
Thuận lợi của mô hình này: chương trình thường đơn giản, không quantâm đến việc chia sẻ dữ liệu giữa các tác vụ
Bất lợi: việc quản lý dữ liệu cục bộ sẽ là một việc phức tạp, khi nhiều tiếntrình truy xuất dữ liệu đồng thời có khả năng gây ra lỗi cache hoặc bus bịquá tải
b. Bộ nhớ phân tán hay giao diện truyền nhận thông điệp
Mô hình này có các đặc điểm:
- Một tập hợp các tác vụ sử dụng bộ nhớ của riêng nó trong suốt quátrình tính toán
- Các tác vụ có thể trao đổi dữ liệu thông qua cơ chế truyền và nhậnthông điệp
Trang 8- Việc trao đổi dữ liệu thường cần phải có sự hợp tác giữa các tiến trìnhvới nhau Như việc truyền dữ liệu bằng một hàm nào đó cần có hàm đểnhận tương ứng.
Những cơ chế truyền nhận thông điệp thường được hiện thực thông quacác thư viện Người lập trình chỉ cần xác định được phần có thể song songhóa của chương trình và hiện thực nó
Hình 3: Cơ chế truyền thông điệp
Có nhiều thư viện truyền nhận thông đã được ra đời từ năm 1992, trong đóMPI (Message Passing Interface) đã trở thành một tiêu chuẩn công nghiệpthay thế hầu hết các thư viện truyền nhận thông điệp khác
c. Mô hình dữ liệu song song
Mô hình này có những tính chất sau:
- Không gian địa chỉ được thiết kế mang tính toàn cục
- Hầu hết những công việc song song là tập trung xử lý trên những tập
dữ liệu có cấu trúc như là mảng
- Một tập hợp các tác vụ làm việc tập thể trên cùng cấu trúc dữ liệu, tuynhiên mỗi tác vụ lại làm việc trên những phần khác nhau của cấu trúc
dữ liệu đó Chẳng hạn, tác vụ A làm việc trên mảng ARR từ vị trí 1 đến
25, tác vụ B cũng làm việc trên mảng ARR nhưng từ vị trí 26 đến 50
- Những tác vụ này thực thi những hành động giống y như nhau trên tập
dữ liệu mà nó làm việc Chẳng hạn, cộng 4 vào mỗi phần tử của ARR
Trang 9Hình 4: Mô hình dữ liệu song song
Đối với kiến trúc bộ nhớ chia sẽ, dữ liệu sẽ được lưu trữ trên bộ nhớ toàncục Các tác vụ sẽ truy cập dữ liệu này một cách toàn cục
Đối với kiến trúc bộ nhớ phân tán, dữ liệu sẽ được tách ra từng phần và lưutrữ ở bộ nhớ cục bộ của từng tác vụ
1.4 Các bước để thiết kế những chương trình song song
1. Song song hóa bằng tay hay sử dụng công cụ (tự động)
Thông thường việc thiết kế những chương trình song song được làm mộtcách thủ công là chính, người lập trình thường chịu trách nhiệm cho cảviệc thiết kế lẫn việc hiện thực nó
Việc thiết kế thủ công như thế này thường tốn thời gian, phức tạp và ẩnchứa nhiều lỗi
Do đó, nhiều công cụ đã được ra đời với mục đích chính thường là: tựđộng song song hóa một chương trình tuần tự Các công cụ này có thể làmột bộ tiền xử lý hay một trình biên dịch
Nếu như chúng ta chỉ có thời gian và ngân sách hạn chế, thì công cụ tựđộng sẽ là câu trả lời Tuy nhiên, cần phải cân nhắc những điều có thể xảy
ra với công cụ này như: kết quả bị sai, hiệu suất giảm nhiều, hạn chế trongcác vòng lặp…
2. Hiểu vấn đề và chương trình
Trang 10Bước đầu tiên của công việc thiết kế chương trình là phải hiểu rõ vấn đề
mà mình đang gặp phải Sau đó, phải xác định xem liệu chương trình cóthể song song hóa được hay không?
Ví dụ vấn đề có thể song song hóa được: “cho một mảng số nguyên gồm 1triệu phần tử, hãy tìm số nguyên nhỏ nhất trong mảng” Để song song hóa,
ta tách mảng thành n phần bằng nhau, tìm số nhỏ nhất trong mỗi phần vàlàm bước thu thập để tìm số nhỏ nhất của mảng trong danh sách các số nhỏnhất của mỗi phần
Một ví dụ điển hình về vấn đề KHÔNG song song hóa được: “tính toánchuỗi số Fibonacy bằng công thức: F(n) = F(n-1) + F(n-2)” Rõ ràng, việctính toán F(n) sẽ phụ thuộc vào hai số đã tìm ra trước nó là F(n-1) và F(n-2) Do đó, việc song song hóa không thể thực hiện được
Hình 5: Sự phân hoạch dữ liệu
Tách theo chức năng: những chỉ thị dùng để giải quyết vấn đề được tách ra
và phân phối vào các tác vụ Như vậy, mỗi tác vụ sẽ thực hiện những hành động, chức năng khác nhau
Trang 11Hình 6: Sự phân hoạch chức năng
- Độ trể và băng thông: độ trể là thời gian một thông điệp nhỏ nhất (0byte) được gửi từ điểm A đến điểm B Băng thông là số lượng thôngđiệp có thể truyền được trong một đơn vị thời gian Chúng ta khôngnên gửi nhiều thông điệp nhỏ vì có khả năng dẫn đến quá tải Chúng tanên dồn các thông điệp nhỏ và thông điệp lớn để tăng hiệu quả của việcgiao tiếp
- Ngoài ra còn các nhân tố khác như: giao tiếp đồng bộ, bất đồng bộ;phạm vi của giao tiếp; độ hiệu quả…
5. Sự đồng bộ
Sự đồng bộ có thể được thực hiện nhờ các cơ chế như: rào cản (Barrier) –khi task đụng đến rào thì dừng lại; semaphore/mutex – cơ chế đồng bộ dựavào cờ, dùng để bảo vệ dữ liệu chia sẽ; đồng bộ giao tiếp – việc giao tiếpnên được thực hiện đồng bộ giữa các tác vụ tham gia, ví dụ như một tác vụmuốn gửi thông điệp thì nó phải hỏi tác vụ nhận là nó có được phép gửihay chưa…
6. Sự phụ thuộc dữ liệu
Sự phụ thuộc dữ liệu thường xuất hiện trong trường hợp nhiều tác vụ truycập vào cùng một vị trí trên bộ nhớ
Trang 12Ngoài ra, còn có một số nhân tố khác cần quan tâm khi thiết kế chươngtrình song song như: cân bằng tải – phân phối công việc giữa các tác vụsao cho các tác vụ được chạy suốt thời gian thực thi; I/O – thông thườngviệc thực thi các tác vụ I/O là không song song hóa được; phân tích hiệusuât hệ thống – nhằm điều chỉnh chương trình và việc này thường tháchthức hơn rất nhiều so với chương trình tuần tự.
Hình 7: Sự cân bằng tải
Trang 132. MPI (MESSAGE PASSING INTERFACE)
2.1 MPI là gì?
MPI (Message Passing Interface) là một đặc tả cho nhà phát triển hoặcngười dùng sử dụng những thư viện truyền nhận thông điệp Về cơ bản, MPIkhông phải là thư viện mà là đặc tả cho thư viện
MPI chủ yếu phục vụ cho mô hình lập trình song song thông qua việctruyền thông điệp: dữ liệu di chuyển từ một tác vụ này sang tác vụ khác thông qua
Hình 8: Mô hình bộ nhớ phân phối
Những ưu điểm của MPI:
- Tính tiêu chuẩn hóa: MPI là một thư viện có thể coi là có tính tiêuchuẩn cao nhất, nó hỗ trợ hầu như tất cả các nền tảng của tính toán hiệunăng cao Trong thực tế, nó đã thay thế hết các thư viện truyền thôngđiệp khác Ví dụ: nó được sử dụng trong trò chơi DeepBlue của IBM
- Tính di động: hầu như việc biên dịch MPI trên các nền tảng khác nhauđiều rất dễ dàng, không cần chỉnh sửa hoặc chỉnh sửa rất ít mã nguồncủa MPI
- Nhiều chức năng: có khoảng 440 hàm được định nghĩa trong MPI-3,trong đó hỗ trợ hầu hết những chức năng của MPI-1 và MPI-2
- Tính sẵn có: tồn tại nhiều sự cài đặt khác nhau trên các lĩnh vực kể cảnhững lĩnh vực chung hay riêng
Trang 142.2 Cài đặt môi trường MPI
Trong phần này, em sẽ trình bày về cách cài đặt và cấu hình MPI để 2 máy
ảo Centos có thể thực thi song song một chương trình song song
Đầu tiên, ta cần tải mã nguồn của MPI về để build và cài đặt vì Centoskhông hỗ trợ cài đặt từ lệnh yum
Vì phải build từ mã nguồn nên Centos phải cài developer tool trước để cógcc và các gói cần thiết khác
Hình 9: Cài developer tools
Tiếp theo, ta tải mã nguồn của MPI về tại địa chỉ:
http://www.mpich.org/static/downloads/3.0rc1/mpich-3.0rc1.tar.gz (ở đây em sửdụng MPI-3)
Tạo thư mục để giải nén và cài đặt MPI:
$ cd ~; mkdir MPI
$ cd MPI; mkdir mpi-3.0rc1-install
$ tar -xzvf mpich-3.0rc1.tar.gz -C /home/vmcentos/MPI
Trang 15enable-Hình 11: Cấu hình MPI hoàn tất
Giờ ta sẽ biên dịch MPI bằng lệnh make (một công cụ có sẵn trongdeveloper tools)
Hình 12: Hoàn thành việc build
Tiếp theo, cài đặt MPI vào thư mục mpi-3.0rc1-install:
Vì là thư viện liên kết động nên ta phải chỉ cho hệ điều hành biết nơi nào
nó phải vào để tìm tập tin thực thi, hoặc thư viện Ta làm như sau:
$ export PATH=/home/vmcentos/MPI/mpi-3.0rc1-install/bin/:$PATH
$ export install/lib/
LD_LIBRARY_PATH=/home/vmcentos/MPI/mpi-3.0rc1-Việc này cho phép thêm vào hệ thống danh sách thư mục Tuy nhiên, khikhởi động lại thì nó sẽ bị mất Để cho phép khởi động thì ta thêm vào tập tin.bash_profile hai dòng trên
Trang 16Đến bước này, việc cài đặt MPI đã hoàn tất và hệ thống có thể chạy Ta cóthể kiểm tra việc cài đặt bằng cách kiểm tra các tập tin cần thiết:
Hình 14: Kiểm tra việc cài đặt
Các bước trên điều làm tương tự nhau cho hai máy ảo Centos
Vì hệ thống của ta được thiết kế để giao tiếp giữa các tiến trình thông quaMPI, nên mỗi máy cần biết được địa chỉ IP cũng như tên của máy kia Ta cầnchỉnh sửa tập tin cấu hình mạng
# vi /etc/sysconfig/network
Hình 15: Đặt tên cho máy 1
Hình 16: Đặt tên cho máy 2
Thêm địa chỉ IP của cả 2 máy vào tập tin host của cả 2 máy để 2 máy cóthể truy cập lẫn nhau bằng tên máy
Trang 17Hình 17: Cấu hình tập tin hosts
Ở đây, giả sử máy centos_m1 có IP là 192.168.106.133 và máy centos_m2
có IP là 192.168.106.134
Điều cuối cùng của việc cấu hình là đảm bảo 2 máy có thể ssh (truy cập từ
xa bảo mật) lẫn nhau mà không cần mật khẩu (sử dụng định danh)
Trên máy centos_m1:
$ ssh-keygen -> ENTER -> ENTER -> ENTER
$ ssh-copy-id -i ~/.ssh/id_rsa.pub centos_m2 -> Password: king -> ENTER
Kiểm tra cài đặt:
$ ssh centos_m2
Hình 18: Kiểm tra SSH trên máy centos_m1
Làm tương tự trên máy centos_m2, thay đổi vị trí khi ssh-copy-id làcentos_m1
Hình 19: Kiểm tra SSH trên máy centos_m2
Giả sử máy centos_m1 là máy chính (master), còn centos_m2 là máy phụ(slave) Tức là máy centos_m1 sẽ điều khiển quá trình thực thi của một chươngtrình song song Vì thế, ta cần tạo một tập tin tên là “machines” trên máy
Trang 18centos_m1 Tập tin này sẽ liệt kê danh sách tên các máy tham gia trong hệ thốngsong song này.
Trên máy centos_m1:
$ touch machines
$ echo centos_m1 > machines
$ echo centos_m2 >> machines
Giờ là lúc ta chạy thử một chương trình song song có sẵn trong các ví dụcủa MPI Chúng ta sẽ sử dụng tập tin thực thi của MPI để chạy chương trình trênmáy master (centos_m1)
$ mpiexec -n 5 -f machines MPI/mpich-3.0rc1/examples/cpi
Giải thích: chạy chương trình cpi với 5 tiến trình trên các máy được liệt kêtrong tập tin “machines”
Hình 20: Ví dụ về chạy chương trình song song bằng MPI
2.3 Một số hàm MPI dùng trong lập trình song song
1. MPI_Init
- Dùng để khởi động các biến môi trường dành cho MPI
- int MPI_Init( int *argc, char ***argv )
o argc: số lượng tham biến
o argv: con trỏ tham biến
2. MPI_Comm_rank
- Dùng để lấy ID của một tiến trình đang chạy
- int MPI_Comm_rank( MPI_Comm comm, int *rank )
o comm: communicator (chương trình đang chạy được gọi là một
Trang 19o rank: ID của tiến trình (biến đầu ra)
3. MPI_Comm_size
- Dùng để lấy số lượng tiến trình trong một communicator
- int MPI_Comm_size( MPI_Comm comm, int *size )
- int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag,MPI_Comm comm)
o buf: địa chỉ của buffer chuẩn bị gửi
o count: số lượng phần tử trong buffer cần gửi
o datatype: loại dữ liệu của mỗi phần tử buffer cần gửi (các phần
tử phải giống nhau về datatype)
o dest: ID của tiến trình sẽ nhận dữ liệu
o tag: đánh dấu thông điệp
o comm: communicatorCác loại dữ liệu mà MPI có thể cung cấp cho datatype và tương ứng vớikiểu dữ liệu của ngôn ngữ C:
MPI datatype Kiểu của C
MPI_INT intMPI_SHORT shortMPI_LONG longMPI_FLOAT floatMPI_DOUBL
E
double
MPI_CHAR charMPI_BYTE unsigned char
Bảng 1: Kiểu dữ liệu của MPI
Trang 20Khi MPI_Send được gọi, nó sẽ tạm dừng chương trình đang gọi đến khitoàn bộ dữ liệu trong buf được chuyển đi hết.
5. MPI_Recv
- Ngược lại với MPI_Send, MPI_Recv là hàm dùng để nhận thông điệp,
dữ liệu từ một tiến trình nào đó gửi đến
- int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
o buf: địa chỉ của buf dùng để nhận dữ liệu (sẽ là nơi mà MPI ghi
dữ liệu vào)
o count: số lượng phần tử trong buffer cần nhận
o datatype: loại dữ liệu của mỗi phần tử buffer cần nhận
o source: ID của tiến trình gửi dữ liệu
o tag: đánh dấu thông điệp
- int MPI_Finalize( void )
- Tất cả các tiến trình phải gọi hàm này trước khi kết thúc
Trang 213. ỨNG DỤNG MPI VÀO LẬP TRÌNH SONG SONG
sẽ rút ngắn hơn nhiều
3.1.2 Giải quyết vấn đề và mã chương trình
Với hệ thống điện toán song song đã cài đặt ở trên (gồm 2 máy ảo chạyvmcentos), ta sẽ cho hai tiến trình cùng chạy song song Mỗi tiến trình sẽ tính tổngcủa ½ mảng Ví dụ như mảng gồm 1000 phần tử thì tiến trình trên máy centos_m1(master) sẽ tính tổng của 500 phần tử đầu tiên, tiến trình trên máy centos_m2(slave) sẽ tính tổng 500 phần tử tiếp theo
Tuy nhiên, ta nên viết mã làm sao để có thể đáp ứng tốt trong trường hợp
có nhiều tiến trình hơn Giả sử có m tiến trình thì mỗi tiến trình sẽ tính toán trênn/m phần tử
Làm sao để một tiến trình biết nó sẽ tính toán từ phần tử nào? Tiến trìnhroot (có ID là 0) sẽ gửi thông điệp cho các tiến trình khác biết nó phải tính toán từphần tử thứ mấy của mảng và kết thúc tại phần tử thứ mấy Sau khi tính xong, cáctiến trình sẽ gửi kết quả về để tiến trình root tổng hợp
Quá trình tính toán và truyền nhận có thể được tổng hợp bằng hình sau: