Đề tài Song song hóa thuật toán Barnes - Hut với OpenMP

TÓM TẮT KHÓA LUẬN Song song hóa là một giải pháp quan trọng được áp dụng khi giải quyết các vấn đề đòi hỏi phải tính toán lớn thường gặp trong các lĩnh vực khoa học cơ bản Bài toán N- body là một trong những bài toán cơ bản trong lĩnh vực vật lý học thiên thể, liên quan tới lực tương tác giữa các hạt với nhau trong không gian. Có rất nhiều hướng để giải quyết bài toán trên, trong đó có phương pháp sử dụng thuật toán Barnes-Hut. OpenMP là giao diện lập trình ứng dụng API, cung cấp cho người lập trình một giao diện mềm dẻo, có tính khả chuyển trong khi phát triển các ứng dụng song song trên các máy tính sử dụng kiến trúc bộ nhớ chia sẻ. Khóa luận này giới thiệu tổng quan về bài toán N-body, thuật toán Barnes-Hut và giao diện lập trình ứng dụng OpenMP. Trên cơ sở đó đánh giá hiệu năng thuật toán Barnes-Hut, tiến hành tìm hiểu, phân tích và đề xuất các phương thức song song hóa thuật toán Barnes-Hut với OpenMP. LỜI CẢM ƠN Đầu tiên, em muốn gửi lời cảm ơn sâu sắc nhất tới TS. Nguyễn Hải Châu, người đã hướng dẫn và chỉ bảo em tận tình trong suốt thời gian làm khóa luận. Em xin chân thành cảm ơn thầy Phạm Kỳ Anh, giám đốc Trung tâm Tính toán hiệu năng cao – Trường Đại học KHTN – Đại học Quốc gia Hà Nội, người đã tạo điều kiện tốt nhất cho em thực hành và thử nghiệm thuật toán. Em cũng xin gửi lời cảm ơn tới tất cả các thầy và các anh chị trong Trung tâm, những người đã giúp đỡ và trả lời mọi thắc mắc, tạo điều kiện cho em hoàn thành khóa luận. Em xin cảm ơn thầy Đoàn Minh Phương, giảng viên bộ môn Mạng và Truyền thông máy tính, khoa CNTT, trường Đại học Công nghệ, người đã giúp đỡ em thử nghiệm bài toán trên máy đa xử lý Intel. Cuối cùng, em xin gửi lời cảm ơn sâu sắc tới những người thân trong gia đình em, những người luôn quan tâm, động viên khích lệ em trong học tập và trong cuộc sống. Sinh viên thực hiện khóa luận Lê Thị Lan Phương Mục lục TÓM TẮT KHÓA LUẬN . i LỜI CẢM ƠN . ii Danh sách hình vẽ iii Bảng từ viết tắt . iv Mục lục v MỞ ĐẦU 1 Chương 1: BÀI TOÁN N-BODY VÀ THUẬT TOÁN BARNES-HUT 2 1.1 Bài toán N-body 2 1.1.1 Giới thiệu bài toán N-body 2 1.1.2 Phương pháp nhằm tăng tốc bài toán N-body . 5 1.1.3 Cấu trúc cây Quadtree và Octree . 7 1.2 Thuật toán Barnes-Hut 9 1.2.1 Mô tả thuật toán Barnes-Hut . 10 Chương 2: GIỚI THIỆU VỀ OPENMP . 15 2.1 OpenMP (Open specifications for Multi Processing) . 15 2.2 Kiến trúc bộ nhớ chia sẻ 16 2.3 Mục tiêu của OpenMP . 17 2.4 Môi trường hỗ trợ OpenMP . 18 2.5 Mô hình lập trình OpenMP . 18 2.6 Một số chỉ thị cơ bản trong OpenMP 19 2.6.1 Các chỉ thị song song hóa 20 2.6.2 Chỉ thị khai báo miền song song . 20 2.6.3 Chỉ thị liên quan tới môi trường dữ liệu 21 2.6.4 Chỉ thị liên quan tới chia sẻ công việc 23 2.6.5 Chỉ thị đồng bộ hóa . 28 2.6.6 Thư viện và một số biến môi trường . 31 2.7 Ví dụ về lập trình song song với OpenMP 33 2.7.1 omp_hello.c . 33 2.7.2 Cách biên dịch . 33 2.7.3 Kết quả 34 Chương 3: SONG SONG HÓA THUẬT TOÁN BARNES-HUT 35 3.1 Treecode 35 3.1.1 Cấu trúc dữ liệu của cây 35 3.1.2 Các biến toàn cục 39 3.2 Thử nghiệm và đánh giá hiệu năng của treecode 40 3.2.1 Thử nghiệm chương trình treecode . 40 3.2.2 Đánh giá hiệu năng 42 3.3 Song song hóa treecode với OpenMP . 43 3.3.1 Môi trường thực hiện song song . 43 3.3.2 Thực hiện song song 44 3.4 Kết quả thực nghiệm . 51 KẾT LUẬN . 53 TÀI LIỆU THAM KHẢO 54 Danh sách hình vẽ Hình 1: Minh họa hệ N-body trong không gian 2 Hình 2: Biểu diễn lực tổng hợp tác dụng lên 1 hạt 4 Hình 3: Quan sát thiên hà Andromeda từ trái đất 6 Hình 4: Biểu diễn quá trình đệ quy thay thế một cụm bởi tâm điểm 7 Hình 5: Cây Quadtree với 4 mức 8 Hình 6: Cây Octree với 2 mức .8 Hình 7: Biểu diễn cây sau khi loại bỏ các ô trống .9 Hình 8: Các thành phần trong OpenMP 15 Hình 9: Kiến trúc bộ nhớ chia sẻ 16 Hình 10: Mô hình Fork-Join .19 Hình 11: Minh họa vùng được song song hóa 21 Hình 12: Hình minh họa chỉ thị Do/for 24 Hình 13: Hình minh họa chỉ thị sections 26 Hình 14: Hình minh họa chỉ thị single 28 Hình 15: Cấu trúc dữ liệu cây trong treecode (1) 36 Hình 16: Cấu trúc dữ liệu cây trong treecode (2) 39 Bảng từ viết tắt Từ hoặc cụm từ Từ viết tắt Từ tiếng Anh Giao diện lập trình ứng dụng API Application Program Interface Các chỉ thị mở dành cho đa xử lý OpenMP Open Specifications for Multi Processing Luồng Thread Thread Hạt body Body Ô, Khối cell Cell Nút node Node Giao diện truyền thông điệp MPI Message Passing Interface Tâm khối Center of mass

pdf61 trang | Chia sẻ: lvcdongnoi | Lượt xem: 2481 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Đề tài Song song hóa thuật toán Barnes - Hut với OpenMP, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
i lượng và vị trí tâm khối trong hộp. Giả sử θ (theta) là ngưỡng (góc mở) cần tính toán (thông thường 0 < θ <= 1). Nếu D/r < θ, ta tính lực hấp dẫn tác dụng lên các hạt như sau. • (x, y, z) là vị trí của hạt trong không gian 3 chiều. • m là khối lượng của hạt. • (xcm, ycm, zcm) là vị trí của tâm hạt trong hộp • mcm là tổng khối lượng các hạt có trong hộp • G là hằng số hấp dẫn Khi đó lực hấp dẫn sẽ được tính theo công thức xấp xỉ là: Force = G * m * mcm * ( (xcm-x)/r3, (ycm-y)/r3, (zcm-z)/r3) (*) Trong đó r = sqrt ((xcm-x)2 + (ycm-y)2 + (zcm-z)2 ) là khoảng cách từ hạt tới tâm các hạt có trong hộp. Nếu D/r >= θ, quá trình tính lực tác dụng lên một hạt được áp dụng đệ quy. Lực tác dụng lên hạt bằng tổng các lực ở các nút con tác dụng lên hạt đó. Thuật toán tính lực tác dụng lên hạt ở bước này có thể được mô tả như dưới đây. Kích thước của hộp Khoảng cách từ hạt tới tâm khối Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 13 ... với mỗi hạt, duyệt cây để tính lực tác dụng lên nó For i = 1 to n f(i) = TreeForce(i,root) end for function f = TreeForce(i,n) ... tính lực hấp dẫn tác dụng lên hạt i ... dựa vào tất cả các hạt có trong nút n f = 0 if n chứa 1 hạt f = lực tính được dựa vào công thức (*) else r = khoảng cách từ hạt i tới tâm khối tại n D = kích thước của cell n if D/r < theta tính lực f dựa vào công thức (*) else for tất cả các con c của n f = f + TreeForce(i,c) end for end if end if Qua thuật toán trên ta nhận thấy: quá trình duyệt cây để tính lực tác dụng lên hạt là độc lập đối với mỗi hạt. Bởi vậy có thể tiến hành song song hóa quá trình này để nhằm tăng tốc bài toán N-body. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 14 Hiện nay, đã có rất nhiều giải thuật nhằm song song hóa quá trình tính toán lực tác dụng trong hệ thống N-body. Có hai hướng để tiến hành song song hóa thuật toán. 1) Song song hóa với MPI - sử dụng bộ nhớ phân tán 2) Song song hóa với OpenMP - sử dụng bộ nhớ chia sẻ Trong khóa luận này, ta sẽ xem xét phương pháp song song hóa thuật toán Barnes-Hut với OpenMP. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 15 Chương 2: GIỚI THIỆU VỀ OPENMP 2.1 OpenMP (Open specifications for Multi Processing) Lập trình song song trên các máy với bộ nhớ chia sẻ đóng vai trò khá quan trọng trong tính toán hiệu năng cao. Tuy nhiên việc sử dụng những tiện ích của hệ thống bộ nhớ chia sẻ là không dễ dàng đối với người lập trình. Giao diện truyền thông điệp MPI phần lớn được sử dụng trong các hệ thống bộ nhớ phân tán. Khả năng mở rộng và tính khả chuyển trong MPI là rất tốt, nhưng nó lại không có ý nghĩa khi triển khai với những đoạn mã viết cho các máy tính tuần tự. Hơn nữa MPI lại không tận dụng được những tiện ích mà hệ thống bộ nhớ chia sẻ mang lại. Trong nhiều năm, có nhiều sản phẩm được giới thiệu nhằm đưa ra tính khả chuyển và hiệu năng cao trên những hệ thống cụ thể. Tuy nhiên vẫn phát sinh những vấn đề trong tính khả chuyển khi sử dụng các sản phẩm này. OpenMP được coi như một giao diện lập trình ứng dụng API (Application Program Interface) chuẩn dành cho lập trình với bộ nhớ chia sẻ. OpenMP là sự kết hợp của các chỉ thị biên dịch, các hàm thư viện, và các biến môi trường được sử dụng để xác định phần thực hiện song song trên bộ nhớ chia sẻ trong lập trình Fortran hoặc C/C++. OpenMP đưa ra một mô hình lập trình song song có tính khả chuyển đối với những kiến trúc bộ nhớ chia sẻ đối với các nhà cung cấp khác nhau. Hình 8: Các thành phần trong OpenMP Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 16 2.2 Kiến trúc bộ nhớ chia sẻ Hệ thống bộ nhớ chia sẻ bao gồm nhiều bộ xử lý CPU, mỗi bộ xử lý truy cập tới bộ nhớ chung thông qua các siêu kết nối hoặc các đường bus. Việc sử dụng không gian địa chỉ đơn làm cho mỗi bộ xử lý đều có một cái nhìn giống nhau về bộ nhớ được sử dụng. Truyền thông trong hệ thống bộ nhớ chia sẻ thông qua cách đọc và ghi dữ liệu giữa các bộ xử lý với nhau lên bộ nhớ. Với cách này, thời gian truy cập tới các phần dữ liệu là như nhau, vì tất cả các quá trình truyền thông đều thông qua đường bus. Ưu điểm của kiến trúc này là dễ dàng lập trình, bởi vì không có một sự truyền thông chính tắc bắt buộc nào giữa các bộ xử lý với nhau, chúng chỉ đơn giản là truy cập tới bộ nhớ chung. Điều khiển quá trình truy cập tới bộ nhớ chung thông qua các kỹ thuật được phát triển trong các máy tính đa nhiệm, như kỹ thuật semaphores… Để tránh tình trạng thắt nút cổ chai, gây ra bởi việc nhiều bộ xử lý truy cập tới cùng một vị trí trong bộ nhớ, người ta chia bộ nhớ chung thành các module. Mỗi module nhớ được kết nối với một bộ xử lý thông qua một mạng chuyển mạch hiệu năng cao. Hình 9: Kiến trúc bộ nhớ chia sẻ Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 17 Một số ví dụ về các máy tính bộ nhớ chia sẻ: • SGI Origin2000: là sự kết hợp hiệu quả giữa kiến trúc bộ nhớ chia sẻ và bộ nhớ phân tán. Bộ nhớ được phân tán về mặt vật lý giữa các nút, với 2 bộ xử lý tại mỗi nút. Quyền truy cập tới bộ nhớ cục bộ của các bộ xử lý tại các nút là như nhau. Xét theo khía cạnh kiến trúc chia sẻ, tất cả các nút đều có quyền truy cập giống nhau tới bộ nhớ phân tán vật lý ( • Sun HPC servers, như Enterprise 3000 (gồm từ 1 đến 6 bộ xử lý) hoặc Enterprise 10000 (gồm 4 đến 64 bộ xử lý). ( • HP Exemplar series, như S-class (gồm 4 đến 16 bộ xử lý), X-class (tới 64 bộ xử lý) ( • DEC Ultimate Workstation. Gồm 2 bộ xử lý, nhưng tốc độ của mỗi bộ xử lý rất cao (533 MHz) ( html). 2.3 Mục tiêu của OpenMP • Cung cấp giao diện chuẩn: OpenMP đưa ra một giao diện chuẩn cho các hệ thống máy tính bộ nhớ chia sẻ. • Tính đơn giản: bao gồm tập các chỉ thị đơn giản và dễ sử dụng cho lập trình trên hệ thống máy tính bộ nhớ chia sẻ. Một chương trình song song hóa có thể chỉ cần sử dụng 3 hoặc 4 chỉ thị biên dịch. • Tính dễ sử dụng: o Khả năng để thực hiện song song cho các chương trình tuần tự. o Khả năng thực hiện song song hóa ở mức thô sơ, hoặc mức chi tiết. • Tính khả chuyển: hỗ trợ Fortran, C, C++ Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 18 2.4 Môi trường hỗ trợ OpenMP Qua tìm hiểu, ta thấy OpenMP là một mô hình lập trình ứng dụng song song dựa trên nền tảng của kiến trúc bộ nhớ chia sẻ, có tính khả chuyển và có thể mở rộng, giúp cho người lập trình có được một giao diện đơn giản và mềm dẻo khi xây dựng ứng dụng. OpenMP được xây dựng dựa trên sự hợp tác của các tập đoàn: • Digital Equipment Corp. ( • IBM ( • Intel Corporation ( • Kuck & Associates Inc. ( • Silicon Graphics Inc. ( Ngày nay nhiều hãng phần cứng, phần mềm và các nhà phát triển ứng dụng chính đều đang xác nhận tính năng của OpenMP. Xem chi tiết tại website để cập nhật thông tin cũng như các phiên bản, các chuẩn dành cho OpenMP. Ví dụ về một vài trình biên dịch có hỗ trợ OpenMP: • Absoft Pro FortranMP 6.0 ( • IBM XL Fortran ( • KAI KAP/Pro Toolset ( 2.5 Mô hình lập trình OpenMP OpenMP dựa trên việc sử dụng số lượng các luồng hiện có trong lập trình song song bộ nhớ chia sẻ. Đó là một mô hình lập trình chính tắc, cung cấp đầy đủ các điều khiển cho người lập trình. Có thể xem mô hình lập trình OpenMP như là một mô hình Fork-Join. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 19 Hình 10: Mô hình Fork-Join Trong mô hình Fork-Join, tất cả các chương trình OpenMP đều bắt đầu bởi một tiến trình đơn. Đó là master thread (luồng chính). Luồng chính này được thực hiện tuần tự cho đến khi gặp chỉ thị khai báo vùng cần song song hóa. Fork: sau khi gặp chỉ thị khai báo song song, master thread sẽ tạo ra một nhóm các luồng song song. Khi đó, các câu lệnh trong vùng được khai báo song song sẽ được thực hiện song song hóa trên nhóm các luồng vừa được tạo. Join: khi các luồng đã thực hiện xong nhiệm vụ của mình, chúng sẽ tiến hành quá trình đồng bộ hóa, ngắt luồng, và chỉ để lại 1 luồng duy nhất là master thread. 2.6 Một số chỉ thị cơ bản trong OpenMP Kỹ thuật để song song hóa đoạn code chính là các chỉ thị biên dịch. Chỉ thị biên dịch được thêm vào mã nguồn, để chỉ ra phần nào được tiến hành song song trên hệ thống bộ nhớ chia sẻ. Cùng với đó là một số chỉ thị đặc biệt chỉ ra phương thức song song hóa như thế nào? Ưu điểm của kỹ thuật này là dễ sử dụng và có tính khả chuyển đối với hệ thống các máy tính tuần tự và máy tính đa xử lý. Bởi vì đối với các trình biên dịch tuần tự, những chỉ thị này được coi như là các comment. Chú ý khi sử dụng thuật ngữ. OpenMP hỗ trợ ngôn ngữ C/C++ và Fortran. Tuy giống nhau về mặt ngữ nghĩa, song cấu trúc khai báo các chỉ thị của OpenMP lại khác nhau. Ví dụ: • Fortran: Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 20 f77: !$OMP PARALLEL f77: call work(x,y) f77: !$OMP END PARALLEL • C/C++: C/C++: #pragma omp parallel C/C++: { C/C++: work(x,y); C/C++: } Dưới đây là tóm tắt các chỉ thị cơ bản khi lập trình với OpenMP (dùng trong ngôn ngữ C/C++) 2.6.1 Các chỉ thị song song hóa Các chỉ thị song song hóa được thêm vào mã nguồn có cấu trúc như sau. Cấu trúc: #pragma omp directive_name [clauses] Chú ý: cuối các chỉ thị song song đều phải xuống dòng. 2.6.2 Chỉ thị khai báo miền song song Chỉ thị này xác định vùng cần tiến hành song song hóa. Khi một thread bắt gặp chỉ thị khai báo miền cần song song, nó sẽ tạo ra một nhóm các thread khác nhau, đồng thời trở thành master thread. Master thread có ID là 0. Số lượng các thread được xác định thông qua biến môi trường hoặc qua lời gọi hàm thư viện. Các thread này sẽ thực hiện đoạn mã nằm trong khai báo song song. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 21 Hình 11: Minh họa vùng được song song hóa Cấu trúc: #pragma omp parallel [clause [clause]…] strutured block Trong đó clause có thể là: • private • shared • default • firstprivate • reduction • if (scalar_logical_expression) • copyin 2.6.3 Chỉ thị liên quan tới môi trường dữ liệu • private (list): khai báo danh sách các biến là private đối với mỗi thread. Điều đó có nghĩa một quá trình xử lý sẽ sử dụng một bản sao các biến. Tham chiếu tới các biến gốc được thay thế bởi tham chiếu tới các bản sao. Vùng liên tục Vùng song song Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 22 • firstprivate (list): giống với khai báo private, song bản sao danh sách các biến được gán giá trị ban đầu là giá trị của các biến gốc. • lastprivate (list): giống với khai báo private, các biến gốc trong danh sách sẽ được gán giá trị là giá trị cuối cùng sau khi ra khỏi vòng lặp hoặc ra khỏi một section. • shared (list): tất cả các thread đều có quyền truy cập tới cùng một danh sách các biến được khai báo là shared. Về thực chất, biến được chia sẻ chiếm một vị trí cụ thể trong bộ nhớ. Mọi thread có thể đọc và ghi thông qua địa chỉ nhớ đó. Vấn đề đặt ra là phải đảm bảo cho các thread truy cập một cách hợp lý tới các biến chia sẻ. • default (shared | none): thiết lập thuộc tính mặc định cho tất cả các biến được sử dụng trong vùng song song hóa. Riêng các biến trong khai báo threadprivate không chịu ảnh hưởng của default. Các biến có thể được khai báo chính tắc là private, shared…mà không cần phải khai báo default. • reduction (operator : list): cho phép các biến thuộc list (biến shared) có các bản sao là private trong mỗi thread. Các thread sẽ thực hiện và ghi giá trị vào biến private đó. Kết thúc chỉ thị reduction, biến shared trong list được lấy giá trị từ các biến private ở mỗi thread bằng cách áp dụng toán tử operator. Toán tử operator có thể là các phép +, *, -, max, min, … • schedule (type [, chunk_size]): Chỉ thị này chỉ ra cách thức vòng lặp for được phân chia như thế nào giữa các thread, thường được sử dụng để tạo trạng thái cân bằng tải giữa các thread. Trong đó type có thể là: static, dynamic, guided, hoặc runtime o static: Nếu không chỉ ra chunk_size thì chunk_size được gán bằng CEILING(tổng số lần lặp/số luồng). Các chunk được gán lần lượt cho các thread (tức là theo kiểu round-robin) o dynamic: Nếu không chỉ ra chunk_size thì chunk_size được gán bằng 1. Các chunk được gán cho các thread theo kiểu: thread nào rỗi hoặc đến trước thì thực hiên trước (first-come first-do). Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 23 o guided: Nếu không chỉ ra chunk_size thì chunk_size được gán bằng 1. Nếu chỉ ra chunk_size thì tổng số lần lặp sẽ được chỉ ra sao cho cỡ của các chunk nối tiếp nhau (theo chỉ số tăng dần) hay chunk_size giảm theo hàm mũ. chunk_size chính là cỡ của chunk bé nhất. Cách làm: chunk_size đầu tiên = CEILING(số lần lặp chia cho số thread). các chunk_size tiếp theo = CEILING(số lần lặp còn lại chia cho số thread) Khi thực hiện, nếu số lượng chunk lớn hơn số thread thì thread nào thực hiện xong phần việc của mình sẽ đảm nhiệm chunk tiếp theo chưa được thực hiện. o runtime: Chunk_size sẽ được xác định khi chương trình được thực hiện. Kiểu schedule sẽ là static hoặc được chỉ ra thông qua biến môi trường OMP_SCHEDULE (như vậy có thể là DYNAMIC, GUIDED...) • threadprivate: #pragma omp threadprivate (list) Chỉ thị threadprivate được sử dụng để làm cho các biến có phạm vi toàn cục trở thành cục bộ và tiếp tục tồn tại trong mỗi thread trong suốt các quá trình cần được song song hóa. Chỉ thị phải được xuất hiện ngay sau khi khai báo biến. Sau đó mỗi thread sẽ làm việc với một bản sao các biến. • copyin (list): gán giá trị cho các biến được khai báo là threadprivate trong các thread bằng giá trị của các biến gốc trong master thread trước khi thực hiện song song. List chứa danh sách các biến để sao chép. 2.6.4 Chỉ thị liên quan tới chia sẻ công việc 2.6.4.1 Do/for Chỉ thị Do/for cho biết vòng lặp for nằm trong khai báo phải được thực thi song song. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 24 Hình 12: Hình minh họa chỉ thị Do/for Cấu trúc: #pragma omp for [clause [clause]…] C/C++ for loop Trong đó clause có thể là: • private (list) • firstprivate (list) • lastprivate (list) • reduction (operator:list) • schedule (type [,chunk_size]) • ordered • nowait Ý nghĩa của private, firstprivate, lastprivate, reduction, schedule đã được mô tả ở mục 6.3. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 25 o ordered: phải được xuất hiện khi trong vòng lặp for có sử dụng chỉ thị ordered o nowait: cho biết các thread không cần phải tiến hành đồng bộ hóa khi kết thúc vòng lặp song song. Chúng tiếp tục thực hiện các câu lệnh sau vòng lặp mà không cần phải chờ đợi thread nào. Có thể kết hợp giữa khai báo song song với chỉ thị chia sẻ công việc bằng cấu trúc sau: #pragma omp parallel for [clauses] for loop 2.6.4.2 Sections Chỉ thị Sections chỉ ra các đoạn mã được phân chia như thế nào giữa các thread. Một khai báo sections có thể gồm nhiều section con độc lập với nhau. Mỗi một section được thực hiện 1 lần bởi một thread. Nếu thời gian thực hiện là đủ nhanh và cách cài đặt cho phép, một thread có thể thực hiện nhiều hơn 1 section. Nếu số lượng thread nhiều hơn số lượng section, khi đó một vài thread có thể rỗi. Nếu số lượng thread ít hơn so với section, tùy thuộc vào cách cài đặt sẽ xác định các section được thực hiện như thế nào. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 26 Hình 13: Hình minh họa chỉ thị sections Cấu trúc: #pragma omp sections [clause[ clause] . . . ] { [#pragma omp section ] structured-block [#pragma omp section structured-block . . . ] } Trong đó clause có thể là: • private • lastprivate • firstprivate • reduction Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 27 • nowait Ý nghĩa của các thông số trên giống như đã được mô tả ở các phần trước. Có thể kết hợp giữa khai báo sections với khai báo parallel. #pragma omp parallel sections [clauses] { [#pragma omp section ] structured-block [#pragma omp section ] structured-block . . . ] } 2.6.4.3 Single Chỉ thị cho biết đoạn mã nằm trong khai báo single sẽ được thực thi bởi duy nhất một thread. Nếu không có tùy chọn nowait, các thread khác sẽ không thực hiện chỉ thị single và chờ đợi tại điểm cuối của khối lệnh trong khai báo single. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 28 Hình 14: Hình minh họa chỉ thị single Cấu trúc: #pragma omp single [clauses] structured-block Trong đó clause có thể là: • private • firstprivate • nowait 2.6.5 Chỉ thị đồng bộ hóa Xét ví dụ đơn giản dưới đây: 2 thread nằm trên 2 bộ xử lý khác nhau đều cùng thực hiện việc tăng giá trị của biến x vào một thời điểm. (giả sử x = 0) THREAD 1: increment(x) THREAD 2: increment(x) Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 29 { x = x + 1; } THREAD 1: 10 LOAD A, (x address) 20 ADD A, 1 30 STORE A, (x address) { x = x + 1; } THREAD 2: 10 LOAD A, (x address) 20 ADD A, 1 30 STORE A, (x address) Có thể xảy ra trường hợp: • thread1 lưu giá trị x vào thanh ghi A • thread2 lưu giá trị x vào thanh ghi A • thread1 cộng thêm 1 vào giá trị x trong thanh ghi A • thread2 cộng thêm 1 vào giá trị x trong thanh ghi A • thread1 lưu giá trị trong thanh ghi A tại địa chỉ của x • thread2 lưu giá trị trong thanh ghi A tại địa chỉ của x Kết quả: x=1, không phải là 2 như mong đợi. Để tránh tình trạng trên, việc tăng giá trị x phải được đồng bộ hóa giữa các thread để đảm bảo cho kết quả chính xác. Dưới đây là một số chỉ thị liên quan tới đồng bộ hóa. 2.6.5.1 Master Chỉ thị cho biết đoạn mã nằm trong khai báo master sẽ được thực hiện bởi master thread. Các thread khác sẽ bỏ qua đoạn mã này và tiếp tục thực hiện bình thường. Cấu trúc: Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 30 #pragma omp master structured-block 2.6.5.2 Critical Chỉ thị xác định đoạn mã nằm trong khai báo sẽ được truy cập bởi duy nhất một thread vào một thời điểm. Các thread khác sẽ phải chờ cho đến khi không có thread nào thực hiện đoạn mã đó. Cấu trúc: #pragma omp critical [(name)] structured-block 2.6.5.3 Barrier Khi 1 thread gặp chỉ thị barrier, thread đó sẽ phải chờ cho đến khi nào tất cả các thread còn lại đều gặp chỉ thị này. Cấu trúc: #pragma omp barrier 2.6.5.4 Atomic Chỉ thị atomic xác định một vùng bộ nhớ cụ thể nào đó sẽ được cập nhật một cách từng phần, không cho phép nhiều thread cùng thực hiện tại đó vào một thời điểm. Chỉ thị chỉ áp dụng cho các câu lệnh đơn. Cấu trúc: #pragma omp atomic statement_expression Các câu lệnh đơn có thể là: ++x x++ --x x-- Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 31 và các toán tử +, -, *, /, &, ^, |, >> hoặc << 2.6.5.5 Flush Chỉ thị flush sẽ ghi lại các biến visible trong thread vào bộ nhớ. Người lập trình có thể tự xác định quá trình đồng bộ hóa một cách trực tiếp trên bộ nhớ chia sẻ thông qua việc sử dụng flush. Tùy chọn list được sử dụng để xác định danh sách các biến cần flush, nếu không có tùy chọn này tất cả các biến sẽ được ghi lại vào bộ nhớ. Cấu trúc: #pragma omp flush [(list)] 2.6.5.6 Ordered Chỉ thị ordered xác định vòng lặp sẽ được thực hiện theo thứ tự như thể được thực thi trên bộ xử lý tuần tự. Ordered chỉ xuất hiện trong khai báo chỉ thị lặp Do/for. Tại một thời điểm, chỉ có một thread thực hiện công việc trong phần khai báo ordered. Cấu trúc: #pragma omp ordered structured-block 2.6.6 Thư viện và một số biến môi trường 2.6.6.1 Một số hàm trong thư viện của OpenMP Để sử dụng được các hàm có sẵn trong OpenMP, cần phải thêm file header “omp.h” trong khi include các thư viện. #include Một vài hàm cơ bản trong thư viện của OpenMP: • void omp_set_num_threads(int num_threads) • int omp_get_num_threads(void) • int omp_get_max_theads(void) • int omp_get_thead_num(void) • int omp_get_num_procs(void) Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 32 • int omp_in_parallel(void) • void omp_set_dynamic(int dynamic_threads) • int omp_get_dynamic(void) • void omp_set_nested(int nested) • int omp_get_nested(void) • ………… 2.6.6.2 Một số biến môi trường trong OpenMP Biến môi trường được sử dụng để điều khiển quá trình thực thi các đoạn mã song song. Truyền giá trị cho các biến môi trường tùy thuộc vào trình biên dịch và kiến trúc hệ thống bộ nhớ chia sẻ. Có thể truyền giá trị cho biến môi trường bằng: • export tên_biến = giá trị • setenv tên_biến giá_trị ví dụ: export OMP_NUM_THREADS=5 setenve OMP_NUM_THREADS 5 Một số biến môi trường thường gặp: • OMP_SCHEDULE • OMP_NUM_THREADSOMP_DYNAMIC • OMP_NESTED Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 33 2.7 Ví dụ về lập trình song song với OpenMP 2.7.1 omp_hello.c Chương trình minh họa hoạt động của các thread khi thực hiện song song. • Biến tid được khai báo là private, lưu ID của mỗi thread. • Biến private nthreads cho biết số lượng thread tham gia vào quá trình song song. 2.7.2 Cách biên dịch Tùy theo các nhà cung cấp và trình biên dịch hiện sử dụng, có thể có nhiều cách để biên dịch một chương trình OpenMP. Với hệ thống máy IBM, dùng cờ -qsmp=omp Với hệ thống máy Intel, dùng cờ -openmp Với hệ thống Compag, dùng cờ -omp /* omp_hello.c */ #include int main () { int nthreads, tid; /* Fork a team of threads giving them their own copies of variables */ #pragma omp parallel private(nthreads, tid) { /* Obtain thread number */ tid = omp_get_thread_num(); printf("Hello World from thread = %d\n", tid); /* Only master thread does this */ if (tid == 0) { nthreads = omp_get_num_threads(); printf("Number of threads = %d\n", nthreads); } } /* All threads join master thread and disband */ Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 34 Trên máy IBM AIX, để dịch chương trình “omp_hello.c”, dùng lệnh: xlc_r –qsmp=omp omp_hello.c –o hello Để thực hiện chương trình, gõ lệnh: ./hello Nếu không chỉ rõ số lượng thread cần sử dụng để thực hiện quá trình song song, thì chương trình sẽ lấy số thread mặc định hiện có trong hệ thống kiến trúc bộ nhớ chia sẻ. Có thể xác định số thread cần thiết thông qua hàm thư viện omp_set_num_threads(int num_threads) hoặc truyền giá trị cho biến môi trường OMP_NUM_THREADS bằng lệnh: export OMP_NUM_THREADS Giả sử, trong ví dụ trên đặt số thread là 4: export OMP_NUM_THREADS=4 Xem trang để biết thêm chi tiết về một số chỉ thị biên dịch. 2.7.3 Kết quả Hello World from thread = 0 Number of threads = 4 Hello World from thread = 3 Hello World from thread = 1 Hello World from thread = 2 Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 35 Chương 3: SONG SONG HÓA THUẬT TOÁN BARNES-HUT 3.1 Treecode Để tiến hành song song hóa thuật toán Barnes-Hut với bài toán N-body, ta xét chương trình treecode của J. Barnes làm ví dụ. Treecode là một trong những chương trình mô phỏng bài toán N-body. Dựa trên nền tảng của thuật toán Barnes-Hut, treecode thực hiện nhanh hơn và kiểm soát lỗi tốt hơn so với các chương trình mô phỏng hệ N-body trước đó. Như đã biết, trong thuật toán Barnes-Hut, sau khi xây dựng cây Quadtree (hoặc Octree), ta tiến hành duyệt cây để tính lực tác dụng lên từng hạt. Tuy nhiên, việc duyệt cây tốn rất nhiều thời gian. Treecode giảm thiểu chi phí cho duyệt cây bằng cách sử dụng tính chất: các hạt liền kề có danh sách các tương tác với nó là giống nhau. Ý tưởng này đã được sử dụng trước đó để nhằm tăng tốc khi tính toán lực trên các máy vector [3], nhưng các chương trình đó chỉ đơn giản áp dụng tìm kiếm cây trong một khối hạt nhỏ. Treecode áp dụng cho tất cả các mức của cây. Lực tác dụng lên các hạt được tính thông qua một vòng duyệt cây đệ quy. Quá trình duyệt cây đệ quy này lưu trữ và cập nhật danh sách các tương tác (interaction list). Tại mỗi mức của cây, hạt b (giả sử nằm trong ô c) được sử dụng để phân biệt với danh sách các tương tác mà b có thể có. Khi duyệt đệ quy tới hạt b, danh sách tương tác sẽ được sử dụng để tính lực hấp dẫn và thế năng tại hạt b. 3.1.1 Cấu trúc dữ liệu của cây Cấu trúc dữ liệu chính được sử dụng trong treecode là cây Octree, bao gồm các body và các cell. Lá của cây lưu trữ thông tin của body. Các nút trong của cây là các cell. Tiến hành duyệt toàn bộ cây bắt đầu từ gốc của cây. Cấu trúc cây Octree có thể được biểu diễn đơn giản như sau: Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 36 Hình 15: Cấu trúc dữ liệu cây trong treecode (1) Cấu trúc node biểu diễn các thông tin chung của body và cell. Theo lý thuyết, mỗi một thành phần của cây có thể được biểu diễn là tổ hợp của body và cell. Nhưng cách biểu diễn đó là không hiệu quả, vì cấu trúc của body và cell đòi hỏi không gian bộ nhớ khác nhau. Do vậy người ta sử dụng cấu trúc node để biểu diễn chung cho body và cell. Việc ép kiểu được sử dụng để chuyển con trỏ có kiểu tùy ý thành con trỏ trỏ tới node, body và cell. typedef struct _node { short type; bool update; real mass; vector pos; struct _node *next; } node, *nodeptr; #define Type(x) (((nodeptr) (x))->type) #define Update(x) (((nodeptr) (x))->update) #define Mass(x) (((nodeptr) (x))->mass) #define Pos(x) (((nodeptr) (x))->pos) #define Next(x) (((nodeptr) (x))->next) Trong đó: Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 37 • Type(q) trả lại kiểu của node q, có giá trị là CELL hoặc BODY • Update(q) có giá trị là boolean, cho biết q có cần cập nhật lực tương tác không? • Next(q) là con trỏ, trỏ tới node tiếp theo của q, sau khi tất cả các con của q đã được duyệt. • Mass(q) là khối lượng của hạt q hoặc là khối lượng của tất cả các hạt có trong cell q • Pos(q) là vị trí của hạt q hoặc vị trí của tâm khối trong cell q Cấu trúc body biểu diễn các hạt. typedef struct { node bodynode; vector vel; vector acc; real phi; } body, *bodyptr; #define Vel(x) (((bodyptr) (x))->vel) #define Acc(x) (((bodyptr) (x))->acc) #define Phi(x) (((bodyptr) (x))->phi) Trong đó: • Vel(b) là vận tốc của hạt b • Acc(b) là gia tốc của hạt b • Phi(b) là thế năng của hạt b Cấu trúc cell biểu diễn các nút trong của cây #define NSUB (1 << NDIM) typedef struct { node cellnode; Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 38 #if !defined(QUICKSCAN) real rcrit2; #endif nodeptr more; union { nodeptr subp[NSUB]; matrix quad; } sorq; } cell, *cellptr; #if !defined(QUICKSCAN) #define Rcrit2(x) (((cellptr) (x))->rcrit2) #endif #define More(x) (((cellptr) (x))->more) #define Subp(x) (((cellptr) (x))->sorq.subp) #define Quad(x) (((cellptr) (x))->sorq.quad) Trong đó: • Subq(c) là mảng các con trỏ trở tới các con của c • More(c) là con trỏ trỏ tới con đầu tiên trong các con của c • Quad(c) là ma trận quadrupole moments • Rcrit2(c) là bình phương bán kính mà nếu nằm ngoài bán kính đó, ô cell c được coi như là một cell interaction. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 39 Hình 16: Cấu trúc dữ liệu cây trong treecode (2) 3.1.2 Các biến toàn cục Treecode sử dụng các biến toàn cục. Biến toán cục được sử dụng chung cho tất cả các tệp của chương trình và được khai báo với định nghĩa global. Định nghĩa global như sau: #define global extern Các tham số đầu vào: • theta: cho biết độ chính xác khi tính toán lực. Tham số này không được xác định nếu bản QUICKSCAN được biên dịch • options: là một chuỗi các tùy chọn để điều khiển thời gian chạy • usequad: cờ cho biết có sử dụng quadrupole correctión hay không? Các biến được sử dụng khi xây dựng cây: • root: con trỏ trỏ tới root cell • rsize: kích cỡ của root cell • ncell: số các cell được sử dụng để xây dựng cây • tdepth: chiều cao của cây • cputree: thời gian CPU đòi hỏi để xây dựng cây Các biến được sử dụng khi tính lực: Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 40 • actmax: độ dài lớn nhất của danh sách active trong khi tính lực • nbbcalc: số các tương tác giữa các hạt với nhau • nbccalc: số các tương tác giữa các hạt và các cell • cpuforce: thời gian CPU cần để tính lực 3.2 Thử nghiệm và đánh giá hiệu năng của treecode 3.2.1 Thử nghiệm chương trình treecode Toàn bộ mã chương trình treecode do J. Barnes viết có thể được download tại trang web Treecode được viết bằng ngôn ngữ C (ANSI C). Giả sử chương trình được biên dịch bởi trình biên dịch của hệ điều hành LINUX. Download file treecode.tar.gz tại trang web trên. Để thực hiện chương trình, copy file vào thư mục riêng, rồi thực hiện lệnh gunzip để giải nén tệp. $ gunzip treecode.tar.gz $ tar xvf treecode.tar Thư mục sau đó sẽ chứa các file .c , .h và Makefile Trước khi biên dịch, có thể cần phải chỉnh sửa một số thông tin trong Makefile tùy theo kiến trúc máy tính và trình biên dịch hiện đang sử dụng. Ở đây, ta sửa lại thông tin trong Makefile bằng cách thêm tùy chọn –pg vào các cờ biên dịch: CCFLAGS và cờ LDFLAGS để khi thực hiện chương trình sẽ sinh ra file gmon.out Tùy chọn biên dịch trong Makefile được sửa lại như dưới đây: # Compiler options. # LINUX: CCFLAGS = -pg -DLINUX LDFLAGS = -pg OPTFLAG = -O3 Thực hiện câu lệnh make để dịch nhiều file với nhau Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 41 $ make treecode Thực hiện chương trình bằng ./treecode [tham số] Có thể xem các tham số bằng câu lệnh: ./treecode –help treecode Hierarchical N-body code (theta scan) in= Input file with initial conditions out= Output file of N-body frames dtime=1/32 Leapfrog integration timestep eps=0.025 Density smoothing length theta=1.0 Force accuracy parameter usequad=false if true, use quad moments options= Various control options tstop=2.0 Time to stop integration dtout=1/4 Data output timestep nbody=4096 Number of bodies for test run seed=123 Random number seed for test run save= Write state file as code runs restore= Continue run from state file VERSION=1.4 Joshua Barnes February 21 2001 Khi thực hiện chương trình, kết quả của quá trình tính toán sẽ được hiển thị ra màn hình, có dạng như sau: Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 42 3.2.2 Đánh giá hiệu năng Mặc dù treecode là một cải tiến của thuật toán Barnes-Hut, với tốc độ tính toán lực nhanh hơn và vấn đề kiểm soát lỗi tốt hơn so với các chương trình trước đó, song vấn đề duyệt cây vẫn chiếm đa số thời gian thực hiện chương trình. Có thể xem thời gian thực hiện các hàm trong toàn bộ chương trình thông qua profile của nó. Thực hiện lệnh gprof với chương trình treecode để xem thông tin profile về chương trình như sau: gprof treecode gmon.out > treecode.out Kết quả hiển thị trong file treecode.out có dạng: Hierarchical N-body code (theta scan) nbody dtime eps theta usequad dtout tstop 4096 0.03125 0.0250 1.00 false 0.25000 2.0000 rsize tdepth ftree actmax nbbtot nbctot CPUfc 64.0 13 3.050 1114 1051990 1417390 0.003 time |T+U| T -U -T/U |Vcom| |Jtot| CPUtot 0.000 0.24032 0.25082 0.49114 0.51069 0.00000 0.00576 0.004 rsize tdepth ftree actmax nbbtot nbctot CPUfc 64.0 12 3.108 1121 1054863 1419799 0.003 time |T+U| T -U -T/U |Vcom| |Jtot| CPUtot 0.031 0.24028 0.25075 0.49104 0.51066 0.00001 0.00576 0.007 rsize tdepth ftree actmax nbbtot nbctot CPUfc 64.0 13 3.057 1108 1040044 1422316 0.003 time |T+U| T -U -T/U |Vcom| |Jtot| CPUtot 0.062 0.24029 0.25069 0.49098 0.51059 0.00001 0.00576 0.011 rsize tdepth ftree actmax nbbtot nbctot CPUfc Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 43 Kết quả này có được khi biên dịch và thực hiện chương trình trên máy Intel với 1 CPU, Pentium 4 CPU 2.26GHz, 240MB RAM, hệ điều hành LINUX. Như vậy, qua kết quả trên ta thấy hàm walktree chiếm đến 96.02% tổng số thời gian thực hiện cả chương trình, trong khi phần trăm thời gian thực hiện các hàm khác là rất nhỏ. Do vậy, tuy thời gian thực hiện treecode có nhanh hơn và vấn đề kiểm soát lỗi là tốt hơn so với các chương trình mô phỏng bài toán N-body trước đó, song để tối ưu hóa chương trình treecode, ta tiến hành thử nghiệm song song hóa chương trình với OpenMP trên máy Intel 4 CPU nhằm tăng hiệu năng tính toán. 3.3 Song song hóa treecode với OpenMP 3.3.1 Môi trường thực hiện song song Thực hiện song song hóa thuật toán treecode trên môi trường Intel (R) Xeon (TM) 4 CPU 2.40 GHz. Thông tin chi tiết về cấu hình 1 CPU trên máy Intel được cho dưới đây: processor : 0 vendor_id : GenuineIntel cpu family : 15 model : 2 model name : Intel(R) Xeon(TM) CPU 2.40GHz stepping : 7 Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 96.02 129.09 129.09 65 1.99 1.99 walktree 0.96 130.37 1.29 2466730 0.00 0.00 subindex 0.95 131.65 1.28 65 0.02 0.02 diagnostics 0.76 132.68 1.03 266240 0.00 0.00 loadbody 0.57 133.44 0.76 65 0.01 0.01 hackcofm 0.21 133.72 0.28 65 0.00 0.00 threadtree 0.19 133.97 0.25 65 0.00 0.00 newtree 0.13 134.15 0.18 64 0.00 2.05 stepsystem 0.10 134.28 0.13 65 0.00 0.00 expandbox 0.05 134.35 0.07 130637 0.00 0.00 makecell 0.03 134.39 0.04 69477 0.00 0.00 xrandom 0.01 134.41 0.02 130637 0.00 0.00 setrcrit 0.01 134.43 0.02 8192 0.00 0.00 fpickshell 0.01 134.45 0.02 65 0.00 2.05 treeforce 0.01 134.46 0.01 1 0.01 0.07 testdata Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 44 cpu MHz : 2394.914 cache size : 512 KB Physical processor ID: 0 Number of siblings : 2 fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm bogomips : 4750.85 3.3.2 Thực hiện song song Theo đánh giá hiệu năng của treecode ở mục 3.2.2, ta thấy phần lớn thời gian chương trình dành cho việc thực hiện hàm walktree. Để tăng hiệu năng tính toán của treecode, ta tiến hành song song hóa treecode bằng cách song song hóa các hàm trên. Khó khăn gặp phải trong khi tiến hành song song hóa treecode đó là sự phụ thuộc vào chương trình dịch. Với các trình biên dịch của các kiến trúc máy tính khác nhau sẽ cho thời gian thực hiện từng hàm con trong chương trình treecode là khác nhau. Ví dụ với trình biên dịch của máy IBM eServer Cluster 1600, hệ điều hành AIX5.2 với cấu hình như sau: • 5 node tính toán pSeries 655, mỗi node gồm 8 CPU Power 4+ 64 bit RISC 1.7 GHz của IBM; cache 5.6MB ECC L2, 128MB ECC L3, băng thông: 72.3 GBps; 32GB RAM, băng thông bộ nhớ 51.2 GBps; 6x36 GB HDD. Năng lực tính toán tổng cộng khoảng 240 GFlops (mở rộng tối đa 768 GFlops/16 node). • 1 node quản lý CSM p630: Power4+ 64 bit 1.2 GHz; cache 1.5 MB ECC L2, 8MB ECC L3, băng thông: 12.8 GBps; 1GB RAM, băng thông: 6.4 GBps; 6x36 GB HDD, DVD ROM. • 1 node điều khiển phần cứng HCM: Intel Xeon 3.06 GHz, 1GB RAM, 40 GB HDD, DVD RAM. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 45 • Các node được kết nối với nhau thông qua HPS (High Performance Switch – Switch hiệu năng cao), băng thông 2GBps và GEthernet. • Hệ thống lưu trữ chung: IBM DS4400 và EXP700 kết nối với cụm IBM 1600 thông qua cáp quang với băng thông 2Gbps. • Các node chạy HĐH AIX 5L phiên bản 5.2 Kết quả profile của treecode trên IBM AIX sẽ là: Với trình biên dịch của Intel (R) Xeon (TM) 4 CPU 2.40 GHz, thì phần trăm thời gian thực hiện các hàm của treecode là: % cumulative self self total time seconds seconds calls ms/call ms/call name 42.3 13.85 13.85 .sqrt [8] 34.8 25.23 11.38 532480 0.02 0.02 .sumnode [9] 7.6 27.73 2.50 .__mcount [11] 5.4 29.50 1.77 161645903 0.00 0.00 .sqrtf [12] 4.0 30.81 1.31 16072949 0.00 0.00 .accept [13] 2.6 31.65 0.84 570149 0.00 0.03 .walktree_13_6 [7] 0.8 31.91 0.26 .qincrement [15] 0.5 32.09 0.18 65 2.77 2.77 .diagnostics [18] 0.4 32.22 0.13 2480994 0.00 0.00 .subindex [19] 0.4 32.34 0.12 .__stack_pointer [20] 0.4 32.46 0.12 .qincrement1 [21] 0.3 32.55 0.09 266240 0.00 0.00 .loadbody [16] 0.2 32.61 0.06 65 0.92 1.25 .hackcofm [22] 0.1 32.64 0.03 65 0.46 0.46 .threadtree [25] Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 46 Như vậy, với các trình biên dịch khác nhau, thời gian thực hiện các hàm của treecode là hoàn toàn khác. Vì vậy, việc đánh giá hàm nào tốn nhiều thời gian nhất cũng như cần phải tiến hành song song hóa như thế nào là vấn đề gặp nhiều khó khăn. 3.3.2.1 Phân tích hàm walktree Hàm walktree là hàm đệ quy chính dùng trong khi tính lực. Nguyên mẫu của nó có dạng void walktree(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr,nodeptr p, real psize, vector pmid); Hàm walktree tính lực hấp dẫn lên tất cả các hạt có trong node p thông qua việc duyệt đệ quy p và các con của nó. Tại mỗi thời điểm trong lượt duyệt đệ quy, thông tin của các node từ gốc tới p được lưu trữ trong một tập các node. Tập đó chính là tập các tương tác. Tập này được chia thành 2 tập cell và body riêng biệt, được trỏ bởi các con trỏ tương ứng là cptr và bptr. Phần còn lại của cây được biểu diễn bởi một tập các active node, bao gồm node p và các node xung quanh nó trong không gian. Con trỏ trỏ tới các node này được lưu vào mảng nằm giữa aptr và nptr. Node p có kích thước là psize và vị trí là pmid. Trong vòng lặp chính, walktree duyệt qua tất cả các active node của p, kiểm tra xem node nào sẽ được thêm vào danh sách tương tác, và node nào gần với p đến mức phải kiểm tra các con của nó ở mức tiếp theo của quá trình duyệt đệ quy. Các cell được kiểm Flat profile: Each sample counts as 0.00195312 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 73.87 9.13 9.13 532480 0.02 0.02 sumnode 12.84 10.71 1.59 16013212 0.00 0.00 accept 10.21 11.97 1.26 569962 0.00 0.02 walktree 0.84 12.08 0.10 2466729 0.00 0.00 subindex 0.47 12.14 0.06 266240 0.00 0.00 loadbody 0.46 12.19 0.06 303722 0.00 0.00 walksub 0.27 12.23 0.03 65 0.51 0.51 diagnostics 0.25 12.26 0.03 520 0.06 0.07 hackcofm 0.22 12.28 0.03 520 0.05 0.05 threadtree 0.19 12.31 0.02 266240 0.00 0.03 gravsum 0.14 12.33 0.02 64 0.27 189.50 stepsystem Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 47 tra thông qua hàm accept. Nếu cell cách khá xa p, nghĩa là tỉ số D/r là đủ nhỏ, cell được thêm vào danh sách tương tác của p. Ngược lại, kiểm tra tất cả các con của nó, và thêm vào danh sách các active node. Nếu có danh sách active mới được tạo ra, thì tiếp tục duyệt cây đệ quy ở mức tiếp theo thông qua lời gọi hàm walksub. Hàm walksub thực hiện việc gọi hàm walktree tại các con của p. Ngược lại, nếu không có danh sách active mới nào, tiến hành kiểm tra p. Nếu p là body, thực hiện tính toán lực tại p bằng lời gọi hàm gravsum. Nguyên mẫu của hàm walksub có dạng như sau: void walksub(nodeptr *nptr, nodeptr *np, cellptr cptr, cellptr bptr,nodeptr p, real psize, vector pmid); Các tham số trong hàm walksub có giá trị giống với các tham số trong hàm walktree tại lời gọi hàm. Có 2 trường hợp xảy ra: • Nếu p là cell, khi đó walksub sẽ duyệt qua tất cả các con của p, và gọi hàm walktree tại mỗi nút con đó. • Nếu p là body, walksub sẽ gọi hàm walktree đúng một lần duy nhất, để duyệt nốt danh sách active của nó. Dưới đây là chi tiết của hàm walktree và walksub Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 48 local void walktree(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { nodeptr *np, *ap, q; int actsafe; if (Update(p)) { /* are new forces needed? */ np = nptr; /* start new active list */ actsafe = actlen - NSUB;/* leave room for NSUB more */ for (ap = aptr; ap < nptr; ap++)/* loop over active nodes */ if (Type(*ap) == CELL) { /* is this node a cell? */ if (accept(*ap, psize, pmid)) {/* does it pass the test?*/ Mass(cptr) = Mass(*ap); /* copy to interaction list */ SETV(Pos(cptr), Pos(*ap)); SETM(Quad(cptr), Quad(*ap)); cptr++; /* and bump cell array ptr */ } else { /* else it fails the test */ if (np - active >= actsafe) /* check list has room */ error("walktree: active list overflow\n"); for (q = More(*ap); q != Next(*ap); q = Next(q)) /* loop over all subcells */ *np++= q; /* put on new active list */ } } else /* else this node is a body */ if (*ap != p) { /* if not self-interaction */ --bptr; /* bump body array ptr */ Mass(bptr) = Mass(*ap);/* and copy data to array */ SETV(Pos(bptr), Pos(*ap)); } actmax = MAX(actmax, np - active); /* keep track of max active */ if (np != nptr) /* if new actives listed */ walksub(nptr, np, cptr, bptr, p, psize, pmid); /* then visit next level */ else { /* else no actives left, so */ if (Type(p) != BODY) /* must have found a body */ error("walktree: recursion terminated with cell\n"); gravsum((bodyptr) p, cptr, bptr); /* sum force on the body */ } } } Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 49 3.3.2.2 Song song hóa treecode Ý tưởng song song hóa treecode như sau: • Sử dụng chỉ thị taskq được hỗ trợ bởi trình dịch của máy Intel, để song song hóa hàm đệ quy walktree. • Với các hàm khác, sử dụng các chỉ thị Do/for để song song hóa vòng lặp. Chỉ thị taskq thiết lập môi trường thực hiện các công việc (task). Khi gặp chỉ thị taskq, một trong số các thread sẽ được chọn để thực hiện chỉ thị đó. Một hàng đợi rỗng được tạo ra bởi thread đã chọn. Sau đó, đoạn chương trình nằm trong khối taskq sẽ được thực hiện bởi một thread đơn. Các thread còn lại chờ thực hiện khối công việc sẽ được thêm vào hàng đợi. Các chỉ thị task xác định một khối công việc có thể được thực hiện bởi nhiều thread khác nhau. Khi gặp chỉ thị task trong khai báo taskq, đoạn chương trình local void walksub(nodeptr *nptr, nodeptr *np, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { real poff; nodeptr q; int k; vector nmid; poff = psize / 4; /* precompute mid. offset */ if (Type(p) == CELL) { /* fanout over descendents */ for (q = More(p); q != Next(p); q = Next(q)) { /* loop over all subcells */ for (k = 0; k < NDIM; k++) /* locate each's midpoint */ nmid[k] = pmid[k] + (Pos(q)[k] < pmid[k] ? - poff : poff); walktree(nptr, np, cptr, bptr, q, psize / 2, nmid); /* recurse on subcell */ } } else { /* extend virtual tree */ for (k = 0; k < NDIM; k++) /* locate next midpoint */ nmid[k] = pmid[k] + (Pos(p)[k] < pmid[k] ? - poff : poff); walktree(nptr, np, cptr, bptr, p, psize / 2, nmid); /* and search next level */ } } Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 50 nằm trong khai báo task về mặt lý thuyết sẽ được xếp vào hàng đợi. Hàng đợi sẽ kết thúc khi tất cả các công việc trên đó đã được hoàn thành. Như vậy, với việc sử dụng hàng đợi, hàm walktree có thể được chỉnh sửa lại như sau: Trong hàm gravcal(), lời gọi hàm walktree sẽ được thêm các chỉ thị taskq và task của OpenMP. Trong hàm walksub gọi đệ quy hàm walktree, do vậy sẽ thêm các chỉ thị của OpenMP vào hàm walksub như sau: void gravcalc(void) { ………. ………. active[0] = (nodeptr) root; /* initialize active list */ CLRV(rmid); /* set center of root cell */ /* Add parallel region */ #pragma omp parallel { #pragma intel omp taskq { #pragma intel omp task { walktree(active, active + 1, interact, interact + actlen, (nodeptr) root, rsize, rmid); /* scan tree, update forces */ } } } /* end of parallel region */ cpuforce = cputime() - cpustart; /* store CPU time w/o alloc */ free(active); free(interact); } Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 51 Khi biên dịch chương trình, các chỉ thị của OpenMP sẽ được thực hiện song song. Kết quả thực nghiệm được cho dưới đây. 3.4 Kết quả thực nghiệm Phụ thuộc vào trình biên dịch và cấu hình máy Intel (R) Xeon (TM) với 4 CPU 2.40 GHz, chương trình treecode sau khi thử nghiệm song song với một số chỉ thị của OpenMP sẽ cho thời gian thực hiện các hàm như dưới đây: local void walksub(nodeptr *nptr, nodeptr *np, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { …………… if (Type(p) == CELL) { /* fanout over descendents */ /* add parallel region */ #pragma intel omp parallel taskq shared(q) { for (q = More(p); q != Next(p); q = Next(q)) { #pragma intel omp task captureprivate(q) { for (k = 0; k < NDIM; k++) nmid[k] = pmid[k] + (Pos(q)[k] < pmid[k] ? - poff : poff); walktree(nptr, np, cptr, bptr, q, psize / 2, nmid); } } } /* end of parallel region */ } else { for (k = 0; k < NDIM; k++) nmid[k] = pmid[k] + (Pos(p)[k] < pmid[k] ? - poff : poff); walktree(nptr, np, cptr, bptr, p, psize / 2, nmid); } } Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 52 Như vậy, tùy thuộc vào từng trình biên dịch trên các máy tính có cấu hình khác nhau, kết quả thử nghiệm thu được trên máy đa xử lý Intel chỉ mang tính chất tương đối. Flat profile: Each sample counts as 0.00195312 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 74.84 10.43 10.43 532480 0.02 0.02 sumnode 11.18 11.99 1.56 569962 0.00 0.02 walktree 10.83 13.50 1.51 16013212 0.00 0.00 accept 0.68 13.59 0.09 2466729 0.00 0.00 subindex 0.48 13.66 0.07 266240 0.00 0.00 loadbody 0.29 13.70 0.04 _walksub_202__task4 0.27 13.73 0.04 520 0.07 0.09 hackcofm 0.24 13.77 0.03 266240 0.00 0.04 gravsum 0.22 13.80 0.03 130637 0.00 0.00 _walksub_199__taskq3 0 20 13 82 0 03 65 0 42 0 42 diagnostics Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 53 KẾT LUẬN Kết quả đạt được Sau một thời gian tìm hiểu, nghiên cứu và đánh giá, tôi nhận thấy thuật toán Barnes-Hut và các cải tiến của nó đã góp phần quan trọng khi giải quyết bài toán N-body, với độ phức tạp chỉ là O (N log N). Cũng qua tìm hiểu, tôi thấy OpenMP là một giao diện lập trình ứng dụng song song đơn giản và dễ sử dụng. Nó cung cấp cho người dùng một giao diện mềm dẻo, có tính khả chuyển cao trong khi xây dựng và phát triển các ứng dụng song song trên các kiến trúc máy tính bộ nhớ chia sẻ. Việc cài đặt và thử nghiệm cải tiến của thuật toán Barnes-Hut trên các máy đa xử lý Intel và IBM cũng giúp cho tôi có những kinh nghiệm và thu được một số kết quả thực nghiệm. Để qua đó tôi phân tích và thấy được một số khó khăn khi tiến hành song song hóa. Tuy kết quả thực nghiệm đạt được chưa cao, song qua tìm hiểu tôi đã học hỏi được kinh nghiệm và nâng cao vốn hiểu biết của mình về tính toán hiệu năng cao trên các máy đa xử lý, cũng như kinh nghiệm về sử dụng hệ điều hành Linux. Hướng phát triển Do điều kiện về thời gian nghiên cứu và điều kiện về phần cứng, nên tôi mới chỉ tìm hiểu và tiến hành thử nghiệm song song hóa trên máy đa xử lý Intel. Hướng nghiên cứu tiếp theo của tôi là tiếp tục tìm hiểu, thử nghiệm và tối ưu thuật toán treecode bằng cách tiến hành song song hóa trên máy IBM, cũng như tiến hành song song hóa thuật toán trên các máy đa xử lý kết hợp giữa bộ nhớ chia sẻ và bộ nhớ phân tán. Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 54 TÀI LIỆU THAM KHẢO [1] Josh Barnes & Piet Hut, A hierarchical O(N log N) force – calculation algorithm, Nature, v. 324, December 1986. [2] Fast Hierarchical Methods for the N-body Problem, Part 1 [3] J. E. Barnes, A modified tree code: Don't laugh; It runs, Journal of Computational Physics 87 (1990) 161--170. [4] A. Kawai, J. Makino, High-accuracy treecode based on pseudoparticle multipole method, Proceedings of the 208th Symposium of the International Astronomical Union (Tokyo, Japan, July 10-13, 2001) 305-314. [5] A. Kawai, J. Makino, Pseudo-particle multipole method: A simple method to implement a high-accuracy treecode, The Astrophysical Journal, 550 (2001) L143-L146. [6] A. Kawai, J. Makino, T. Ebisuzaki, Performance analysis of high-accuracy tree code based on the pseudoparticle multipole method, The Astrophysical Journal Supplement 151 (2004) 13-33. [7] Joshua E. Barnes, Institute for Astronomy, University of Hawaii, Treecode Guide [8] Giovanni Erbacci, Shared Memory Paradigm, High Performance Systems Department, CINECA [9] Introduction to OpenMP, Technical User Support, Supercomputing Institute, University of Minnesota [10] OpenMP exercise [11] Michael Süß, Claudia Leopold, A User's Experience with Parallel Sorting and OpenMP, Talk at the EWOMP'04 conference, Stockholm Song song hóa thuật toán Barnes-Hut với OpenMP Lê Thị Lan Phương 55 [12] Dieter an Mey, Two OpenMP Programming Patterns, Center for Computing and Communication, Aachen University [13] Paul Graham, Edinburgh Parallel Computing Centre, The university of Edinburgh, OpenMP A Parallel Programming Model for Shared Memory Architectures,March 1999, version 1.1

Các file đính kèm theo tài liệu này:

  • pdfSong song hóa thuật toán Barnes-Hut với OpenMP.pdf