Khóa luận Song song hóa thuật toán Barnes-Hut với OpenMP

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

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

Lê ThịLan Phương

vi

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

pdf61 trang | Chia sẻ: oanh_nt | Lượt xem: 1895 | Lượt tải: 2download
Bạn đang xem trước 20 trang tài liệu Khóa luận 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
đã 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 c

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