Các hệ thống máy tính đa vi xử lý với mô hình lập trình song song chia sẻ bộ nhớ chung .... • Các hãng sản xuất bộ xử lý đồ họa như nVidia, AMD liên tục đưa ra những hệ thống phần mềm tr
TÍNH TOÁN HIỆU NĂNG CAO VỚI GPU
Một số tiếp cận trong tính toán hiệu năng cao
1.2.1 Các hệ thống máy tính đa vi xử lý v i mô hình l p trình song song ớ ậ chia sẻ ộ b nh chungớ
Kiến trúc SMP (symmetric multiprocessor) là một phương pháp truyền thống trong việc xây dựng các hệ thống máy tính mạnh, cho phép nhiều bộ vi xử lý chia sẻ cùng một vùng bộ nhớ chung Hệ thống SMP sử dụng một hệ điều hành duy nhất, trong khi lập trình viên áp dụng phương pháp lập trình đa luồng để tối ưu hóa hiệu suất tính toán Các ứng dụng được phân chia thành nhiều luồng công việc, cho phép thực hiện trên các bộ xử lý riêng biệt và trao đổi thông tin qua vùng bộ nhớ chia sẻ.
Hai yếu tố cơ bản ảnh hưởng đến hiệu năng hoạt động của một hệ thống SMP là hiệu năng tính toán của các bộ xử lý và băng thông của bộ nhớ chia sẻ Hiệu năng tính toán của một hệ thống SMP được xác định bởi số lượng lõi xử lý và hiệu năng của từng bộ xử lý đơn lẻ, đảm bảo năng lực tính toán tối đa cho hệ thống Tuy nhiên, ứng dụng thường không tận dụng tối đa khả năng tính toán của hệ thống do thiết kế giải thuật song song và băng thông truy cập vào bộ nhớ chia sẻ, đây là những lý do quan trọng ảnh hưởng đến hiệu năng sử dụng trên các hệ thống SMP.
Một ví dụ điển hình về hệ thống SMP là máy tính cá nhân với bộ vi xử lý đa lõi như Intel DualCore và Intel QuadCore, đang được sử dụng phổ biến hiện nay Tuy nhiên, khả năng tính toán của các hệ thống máy tính cá nhân này vẫn chưa thực sự cao để đáp ứng đầy đủ nhu cầu tính toán trong công nghệ, do số lượng và hiệu năng của các bộ xử lý dành cho máy tính cá nhân còn hạn chế.
Hình 1 2 Siêu máy tính NEC SX9 m
NEC SX9 là một hệ thống SMP điển hình, có khả năng xây dựng từ nhiều nút, mỗi nút hỗ trợ tối đa 16 bộ xử lý với hiệu năng lên tới 1.6 Tflops Mỗi nút được trang bị tối đa 1TB bộ nhớ, cùng với băng thông có thể đạt tới 4TB/s.
Mặc dù hệ thống SMP như SX9 có khả năng tính toán cao và ứng dụng thực tiễn đa dạng, nhưng chúng không phổ biến do chi phí sản xuất và vận hành quá lớn, cùng với tính khả dụng của các hệ thống SMP thường thấp Hiện nay, các kiến trúc máy tính khác, đặc biệt là kiến trúc phân cụm, đang được ưa chuộng hơn so với SMP, điều này được thể hiện qua tỷ lệ 83.4% cho hệ thống cluster so với 16.2% cho SMP theo thống kê vào tháng 11/2009.
1.2.2 Cụm máy tính với mô hình lập trình song song truyền thông điệp
Hệ thống tính toán song song phân cụm (Cluster) bao gồm các máy tính song song được xây dựng từ các nút tính toán và thiết bị mạng thông dụng Mỗi nút tính toán hoặc nút điều khiển vào/ra hoạt động độc lập, tạo thành một hệ thống hoàn chỉnh Hệ thống này cho phép thực hiện các tác vụ tính toán phức tạp một cách hiệu quả và nhanh chóng.
• Các tài nguyên tính toán là bộ vi x lý và b nhớ ử ộ trong tại m i máy tính.ỗ
Các tài nguyên tính toán có khả năng kết nối và tương tác thông qua cáp mạng, thường giới hạn trong một mạng cục bộ (LAN) Trong hệ thống này, một máy tính đóng vai trò là máy chủ (server), trong khi các máy tính còn lại hoạt động như các nút tính toán (computing node).
Hình 1.3 Mô hình một Cluster
Hệ thống tính toán song song phân cụm đang ngày càng trở nên phổ biến, đặc biệt phù hợp với các nước đang phát triển và các trường đại học Tuy nhiên, việc triển khai và cấu hình hệ thống tương đối phức tạp, đồng thời hiệu suất hoạt động không ổn định như các siêu máy tính Một trong những thách thức lớn nhất là vấn đề truyền thông giữa các nút tính toán Nghiên cứu nhằm nâng cao khả năng truyền thông là một trong những vấn đề quan trọng hàng đầu trong phát triển các cấu trúc và mô hình hệ thống phân cụm Đối với các hệ thống này, phần mềm đóng vai trò quan trọng, đảm bảo rằng các máy tính riêng lẻ có thể hoạt động ổn định và cộng tác hiệu quả.
1.2.3 Các bộ ử x lý đồ ọ h a với mô hình lập trình song song dữ ệ li u
Trong khi các nhà sản xuất CPU gặp khó khăn trong việc nâng cao hiệu năng, các nhà sản xuất GPU lại tiếp tục hưởng lợi từ định luật Moore Hình 1.4 minh họa sự gia tăng về số lượng phép tính dấu chấm động/giây và băng thông giữa các dòng card đồ họa của Nvidia và CPU Intel.
Hình 1.4 Biểu đồ ố s phép tính dấu chấm động trên giây và d i thông bả ộ nhớ giữa CPU và GPU
• GPGPU (General Purpose computation on GPUs Tính toán thông d- – ụng trên các bộ ử x lý đ h a) ồ ọ
Một câu hỏi thường gặp là tại sao không thiết kế CPU giống như GPU để cải thiện hiệu năng Nguyên nhân chính là CPU được tối ưu hóa để xử lý một chuỗi lệnh phức tạp, bao gồm nhiều loại dữ liệu khác nhau và thực hiện các tác vụ như truy cập bộ nhớ và tính toán rẽ nhánh Để thực hiện các tác vụ này, CPU cần trích xuất nhiều lệnh song song, nhưng việc tăng cường xử lý song song có giới hạn và không mang lại hiệu quả cao.
Cách vận hành của GPU rất đơn giản: đầu tiên, nó tập hợp các đa giác và điểm ảnh thành một nhóm, sau đó xử lý các dữ liệu này hoàn toàn độc lập Điều này cho phép GPU tối ưu hóa tài nguyên của mình để tập trung vào việc xử lý dữ liệu hiệu quả hơn.
Hình 1.5 GPU dành nhiều transistor hơn để ử x lý d liệu ữ
GPU khác với CPU ở cách truy cập bộ nhớ, cho phép ghi và truy xuất dữ liệu từ các điểm ảnh láng giềng trong các chu kỳ tiếp theo Sự tổ chức bộ nhớ thông minh này giúp hiệu suất của bộ nhớ đạt gần mức lý thuyết, đồng nghĩa với việc GPU không cần bộ đệm (cache) lớn như CPU Phần lớn bộ nhớ được sử dụng để tăng tốc độ xử lý texture, trong khi một phần còn lại lưu trữ các điểm ảnh cần thiết cho việc render.
Trong suốt thời gian dài, CPU và GPU đã được thiết kế để thực hiện các nhiệm vụ tương ứng với khả năng của chúng; CPU chủ yếu phục vụ cho việc gõ văn bản và duyệt web, trong khi GPU được tối ưu hóa để tăng tốc xử lý đồ họa và chơi game.
Nhưng đến thời điểm xuất hiện GPU NV30 của NVIDIA (GeForce FX
5800), GPU bắt đầu tham dự vào những công việc khác ngoài đồ họa như :
- Hỗ trợ tính toán dấu chấm động đơn
- Hỗ trợ tính toán lên đến cả ngàn lệnh.
Vào năm 2003, khái niệm GPGPU (Tính toán thông dụng trên các bộ xử lý đồ họa) đã ra đời, đánh dấu bước tiến mới trong việc sử dụng GPU không chỉ cho đồ họa mà còn cho các chương trình tính toán khác Ý tưởng này đã mở rộng khả năng của GPU, cho phép xử lý nhiều loại tác vụ phức tạp hơn.
SC08 đánh dấu sự ra đời của siêu máy tính đầu tiên trên thế giới sử dụng
GPU đã trở thành công cụ quan trọng trong việc tính toán phức tạp và giải quyết các bài toán kinh tế Siêu máy tính Tsubame từ Tokodai (TiTech, Tokyo Institute of Technology) được trang bị 170 khối Tesla dạng 1U, mỗi khối chứa 4 card Tesla, tổng cộng là 680 GPU Tesla Với cấu hình này, Tsubame đứng thứ 29 trong bảng xếp hạng LINPACK Benchmark, đạt khả năng tính toán 77.48 TFLOP với độ chính xác kép trên số thực Đặc biệt, với chi phí lắp đặt thấp hơn nhiều so với hệ thống ban đầu và thời gian lắp đặt kỷ lục, Tsubame đã chứng minh tính khả thi của việc sử dụng GPU trong các hệ thống HPC.
Chính vì vậy mà chỉ sau khi NVIDIA cho ra đ i CUDA vào tháng 2 năm ờ
GIỚI THIỆU KIẾN TRÚC TESLA VÀ MÔ HÌNH LẬP TRÌNH SONG SONG CUDA
Kiến trúc tính toán trên GPU Tesla và mô hình lập trình song song CUDA
GPU hiện nay có độ chính xác cao hơn và khả năng xử lý nhiều điểm mạnh mẽ hơn với tỷ lệ 3:1 Việc tăng cường tính phổ biến của GPU cũng như tối ưu hóa thiết kế phức tạp, vùng miền và giá thành của hai cách xử lý riêng biệt là rất quan trọng Hơn nữa, khả năng tính toán phức hợp có thể lập trình được đang trở thành xu hướng, với nhiều lựa chọn GPU này ngày càng được ưa chuộng hơn so với các GPU không lập trình được Những yếu tố này chính là động lực thúc đẩy sự phát triển của kiến trúc xử lý Tesla.
2.2.1 Kiến trúc tính toán trên GPU Tesla Được NVIDIA giới thi u vào tháng 11 năm 2006, ki n trúc tính toán và đ h a ệ ế ồ ọ hợp nhất Tesla đã phát tri n, gia tăng đáng kể ể v s ề ố lượng so với các GPU đồ họa không lập trình đư c Khả năng xử lý đa luồng với số lượng luồng thực thi ợ cực lớn khiến kiến trúc này trở nên một nền tảng hiệu quả cho cả những ứng dụng tính toán đồ họa và ứng dụng tính toán song song thông thường trên GPU
Hình 2.2 Kiến trúc của 1 card NVIDIA Tesla GPU với 112 lõi xử lý
Kiến trúc Tesla được thiết kế dựa trên cấu trúc của các SM (streaming multiprocessors), với mỗi SM bao gồm 8 lõi xử lý vô hướng SP Những GPU theo kiến trúc này có khả năng thực hiện từ 768 đến hàng nghìn tác vụ song song, mang lại hiệu suất xử lý vượt trội cho các ứng dụng yêu cầu tính toán cao.
GPU hỗ trợ môi trường phát triển ứng dụng CUDA cho phép lập trình viên mở rộng quy mô thực thi song song một cách hiệu quả Điều này có nghĩa là số lượng luồng thực thi không bị giới hạn bởi năng lực của GPU, giúp tăng cường khả năng xử lý song song.
Hình 2.2 trình bày một GPU với 14 SMs - tương đương với 112 lõi SP (streaming processor), kết nối liên thông với 4 mô đun b nhớ ộ DRAM bên ngoài
Chương trình CUDA bao gồm hai phần: thực thi trên CPU và thực thi trên GPU Khi một kernel được gửi từ CPU, nó có thể thực hiện N lần song song qua N luồng CUDA khác nhau, được tổ chức thành lưới gồm nhiều khối (block), mỗi khối chứa nhiều luồng Khi kernel được gửi, đơn vị phân phát công việc tính toán (CWD) sẽ liệt kê các khối trong lưới và phân phối chúng tới các SM sẵn sàng thực thi Các luồng trong một khối được thực hiện đồng thời trên một SM Sau khi các khối hoàn thành, CWD sẽ tiếp tục thực thi các khối mới trên các bộ xử lý rảnh rỗi cho đến khi tất cả các khối trong lưới được thực thi thành công.
Một SM có chứa 8 lõi xử lý vô hướng SP scalar processor (SP), 2 đơn vị – chức năng đặc biệt – special function units (SFUs), dành cho tính toán siêu việt,
Đơn vị điều hướng đa luồng (MTIU) kết hợp với bộ nhớ chia sẻ trên chip (SM) cho phép tạo và quản lý tới 768 luồng đồng thời mà không tốn chi phí lập lịch SM có khả năng thực thi 8 block CUDA cùng lúc, tối ưu hóa hiệu suất phần cứng.
SM ánh xạ nhiều luồng tới một lõi vô hướng, cho phép các luồng vô hướng chạy độc lập với nhau, mỗi luồng có địa chỉ lệnh và trạng thái thanh ghi riêng Đơn vị SM SIMT quản lý, sắp xếp và thi hành các luồng trong một nhóm gồm 32 luồng song song, được gọi là warps.
Các luồng riêng lẻ được sắp xếp theo thứ tự thành một tập hợp warp khởi động đồng thời tại cùng một địa chỉ chương trình, nhưng có khả năng rẽ nhánh và thực thi một cách độc lập Mỗi SM quản lý một nhóm gồm 24 warp.
32 lu ng trên m i warp, và t ng c ng có 768 luồ ỗ ổ ộ ồng
Các lệnh được thực hiện đồng thời trong một warp, với đơn vị SIMT (Single Instruction, Multiple Threads) chọn một lệnh để thực hiện và gửi lệnh tiếp theo đến các luồng đã được chuẩn bị trong warp Mỗi warp thực thi một lệnh chung tại một thời điểm, mang lại hiệu quả cao nhất khi có 32 luồng trong một warp phù hợp với nhau về đường dẫn thực thi Nếu các luồng trong một warp phân nhánh qua một điều kiện, warp sẽ thực hiện từng nhánh, vô hiệu hóa các luồng không nằm trên đường dẫn đó, và khi tất cả các đường dẫn hoàn thành, các luồng sẽ quay lại thực thi trong cùng một đường dẫn Sự phân nhánh xảy ra trong một warp cho phép các warp khác nhau thực thi độc lập mà không cần chú ý đến nhau, dẫn đến kiến trúc GPU Tesla trở nên linh hoạt và hiệu quả hơn trong việc xử lý các nhánh mã so với các GPU trước đây, nhờ vào việc các warp 32 luồng của chúng không bị hạn chế nhiều như các GPU SIMD trước đó.
Kiến trúc SIMT (Single Instruction, Multiple Threads) tương tự như cấu trúc véc-tơ SIMD (Single Instruction, Multiple Data) nhưng cho phép một lệnh điều khiển nhiều luồng xử lý các phần tử Một điểm quan trọng là SIMD chỉ ra sự song song hóa trong mảng dữ liệu, trong khi SIMT nhấn mạnh việc thực thi và trạng thái phân nhánh của một luồng đơn Khác với SIMD, SIMT cho phép lập trình viên viết mã song song phân cấp cho các luồng một cách độc lập và linh hoạt, cũng như mã song song dữ liệu cho việc phối hợp các luồng Mặc dù lập trình viên có thể bỏ qua động thái SIMT, hiệu năng vẫn có thể được cải thiện khi mã được tối ưu hóa để giảm thiểu sự phân rã giữa các luồng trong warp Thực tế, điều này tương tự như vai trò của các dòng đệm trong mã truyền thống, nơi kích thước dòng đệm cần được thiết kế cẩn thận để đảm bảo tính chính xác và hiệu năng tối ưu Các kiến trúc véc-tơ yêu cầu phần mềm kết hợp một khối tải trong các véc-tơ và điều khiển sự phân rã một cách hiệu quả.
Một biến luồng thường được lưu trữ trong các thanh ghi đang sử dụng Bộ nhớ chia sẻ 16Kb SM có độ trễ truy cập thấp và băng thông cao tương tự như bộ nhớ đệm.
Kiến trúc GPU Tesla sử dụng bộ nhớ shared để quản lý các biến CUDA, tối ưu hóa việc kích hoạt khối luồng SM có khả năng nạp và lưu trữ dữ liệu từ bộ nhớ device trên GPU với DRAM gắn ngoài Nó tạo ra một khối truy cập riêng biệt cho các luồng song song trong cùng một warp, giúp cải thiện hiệu suất khi các địa chỉ truy cập nằm trong cùng một khối Để giảm thiểu độ trễ từ bộ nhớ chung, các chương trình CUDA thường sao chép dữ liệu vào bộ nhớ chia sẻ, giúp truy cập nhanh chóng cho các khối luồng Kiến trúc mới nhất của Tesla cũng hỗ trợ các lệnh bộ nhớ đọc-ghi nguyên tử, giảm thiểu xung đột và cải thiện quản lý dữ liệu song song.
Các ứng dụng CUDA hoạt động hiệu quả nhất trên các GPU kiến trúc Tesla nhờ vào khả năng xử lý song song, sự đồng bộ hóa, bộ nhớ chia sẻ và phân cấp các nhóm luồng Những yếu tố này tối ưu hóa các chức năng của kiến trúc GPU, mang lại hiệu suất cao cho các tác vụ tính toán phức tạp.
2.2.2 Mô hình l p trình song song CUDAậ
CUDA là một mở rộng của ngôn ngữ lập trình C, cho phép lập trình viên định nghĩa các hàm, gọi là kernel, để thực thi song song thông qua N luồng CUDA, tương tự như các hàm C truyền thống.
Thiết lập môi trường tính toán CUDA
Để có th ch y đư c các chương trình CUDA, chúng ta c n có m t môi ể ạ ợ ầ ộ trường phù h p, h trợợ ỗ cho CUDA c v ph n c ng và môi trường phần mềm ả ề ầ ứ
Để chạy các ứng dụng CUDA, điều kiện tiên quyết là phải sở hữu một GPU của Nvidia với tính năng CUDA được cài đặt sẵn Hiện nay, các dòng GPU hỗ trợ CUDA bao gồm nhiều loại khác nhau.
• GeForce 8, 9, 100, 200 Bộ nh nh nhớ ỏ ất trên các GPU này là 256Mb
Các thành ph n phầ ần c ng còn lứ ại cấu hình tối thiểu đ ch y các ứng dụng ể ạ CUDA có thể là như sau:
- 1.6 GHz Intel or AMD dual core CPU
- NVIDIA GeForce 8 series or later CUDA enabled GPU
- Windows XP/Vista 32-bit or 64 bit-
2.3.2 B ộ công cụphát triển phần mềm
B ộ công cụ phát triển CUDA của NVIDA gồm có 3 thành phần bao gồm [8] :
2 Một bộ Toolkit CUDA bao gồm:
- CUDA FFT and BLAS libraries for the GPU
- gdb debugger for the GPU
- CUDA runtime driver (also available in the standard NVIDIA GPU driver)
3 Các đoạn mã ví dụ CUDA SDK
B ộ công cụ này có thể ownload tại: D http://www.nvidia.com/object/cuda_get.html
Sau khi đáp ứng yêu cầu về phần cứng và hệ điều hành, chúng ta cần tiến hành cài đặt bộ phát triển công cụ CUDA theo các bước sau đây.
Chú ý rằng quá trình cài đặt CUDA Driver và CUDA Toolkit phải đư c thực ợ hiện trước khi chạy biên dịch các đo n mã nguồ ạ n.
BÀI TOÁN MÔ PHỎNG N- BODY
Ứng dụng của bài toán N Body
Mô phỏng N Body là công cụ quan trọng trong nhiều lĩnh vực khoa học, từ tính toán tĩnh điện học và các lực van der Waals đến việc mô phỏng sự hỗn loạn của chất lỏng Ngoài ra, nó còn được ứng dụng trong đồ họa máy tính để tính toán độ sáng tổng thể và mô phỏng sự tương tác giữa các ngôi sao trong dải ngân hà.
3.3 Các giải thuật với bài toán mô phỏng N-Body
Trong các giải thuật mô phỏng N body, phương pháp tính toán tất cả các cặp (All-pairs) đánh giá lực tương tác giữa từng cặp body, tuy đơn giản nhưng không thường được sử dụng trong các bài toán mô phỏng hệ thống tuần tự do độ phức tạp tính toán lên tới O(N²) Một cải tiến cho phương pháp này là giải pháp nhanh hơn dựa trên sự xấp xỉ miền xa của các lực, cho kết quả gần đúng khi các phần của hệ thống được phân tách Các giải thuật N Body nhanh bao gồm giải thuật Barnes-Hut (BH), Phương pháp đa cực nhanh (FMM) và Giải thuật cây đa cực song song (PMTA).
3.3.1 Giải thuật tương tác hạt hạt (The Particle – - Particle (PP) method)
Giải thuật này tính toán lực tương tác giữa tất cả các cặp body trong hệ thống N body, với sự tương tác giữa hai phần tử độc lập được gọi là sự tương tác giữa 2 phần tử Tuy nhiên, do tính toán tuần tự cho tất cả các cặp, nếu số lượng body lớn, khối lượng tính toán sẽ trở nên khổng lồ.
3.3.2 Giải thuật Barnes-Hut (The Barnes Hut Algorithm)-
Giải thuật Barnes-Hut sử dụng cấu trúc cây phân cấp trong không gian 3 chiều, bao gồm hai phần chính Phần đầu tiên tạo ra kiến trúc cây bằng cách chia nhỏ đệ quy cell gốc thành 8 cell con hình lập phương, cho đến khi mỗi cell con chứa ít nhất một hạt Mỗi cell lưu trữ tổng trọng lượng và vị trí khối tâm của tất cả hạt trong các cell con dưới nó Phần thứ hai duyệt qua cây một lần cho mỗi hạt để tính toán lực tổng hợp tác động lên nó, bắt đầu từ gốc cây Nếu cell phân tách tốt các hạt, lực tác động được tính dựa trên khối tâm thay vì toàn bộ cây con, với điều kiện kích thước cell phân chia bởi khoảng cách từ trọng tâm tới hạt nhỏ hơn tham số Ө, điều khiển độ chính xác Ngoài ra, xấp xỉ đơn cực có thể được thay thế bằng các dạng đa cực để tăng độ chính xác tính toán.
Một số phương án của giải thuật Barnes Hut đã được trình bày trước đây, cho phép tối ưu hóa việc vector hóa mã chi phí cho các phép toán dấu chấm động bậc cao Mặc dù phân tích của chúng ta đã được giới hạn từ phiên bản khởi thủy của giải thuật, nhưng việc mở rộng các phương án đơn giản là hoàn toàn khả thi.
3.3.3 Phương pháp đa cực nhanh (The Fast Multipole Method - FMM)
Sự khác biệt chính giữa FMM và Barnes-Hut nằm ở cách thức tính toán tương tác Barnes-Hut tập trung vào việc tính toán các tương tác hạt-cell, trong khi FMM xử lý các tương tác cell-cell, giúp giảm độ phức tạp tính toán đáng kể.
3.3.4 Giải thuật cây đa cực song song (Parallel Multipole Tree Algorithm -
PMTA là sự kết hợp của hai thuật toán Barner-Hut và FMM, sử dụng quy tắc tương tự Barner-Hut để xác định sự phân tách tốt giữa hai cell Hai cell -H được coi là phân tách tốt nếu kích thước của cell lớn hơn cell nhỏ và bé hơn tham số α Cây được xây dựng theo phương pháp Barner-Hut, nhưng cell được chia nhỏ đệ quy cho đến khi chứa không quá m hạt Khi duyệt cây từ trên xuống, nếu tìm thấy cell phân tách tốt, sẽ thực hiện mở rộng đa cực tại trung tâm của cell đó, trong khi không thăm các phần còn lại của cây con dưới cell Các hạt trong cell tương tác trực tiếp với hạt trong các cell chưa phân tách tốt Số lượng thuật ngữ trong mở rộng đa cực p và tham số phân tách α có thể điều chỉnh để kiểm soát độ chính xác, tuy nhiên, giới hạn lỗi lý thuyết cho thuật toán này vẫn chưa được xác định.
Tổng kết các giải thuật
Giải thuật tương tác hạt hạt có hiệu năng tính toán kém nhất, đạt O(N²), trong đó N là số lượng các body được mô phỏng Khi số lượng body trong bài toán tăng lên, độ phức tạp của bài toán cũng gia tăng đáng kể.
Giải thuật Barnes Hut có độ phức tạp tính toán O(n log n) và dựa trên cấu trúc cây phân cấp trong không gian ba chiều Thuật toán này cho phép tính toán các tương tác giữa các hạt ở khoảng cách xa bằng cách sử dụng phương pháp xấp xỉ theo thứ tự trước.
Here is the rewritten paragraph:Phương pháp đa cực nhanh cho phép tính toán với độ phức tạp O(n), tuy nhiên, nó lại yêu cầu sử dụng nhiều phép tính toán học phức tạp hơn và lập trình khó khăn hơn trong không gian 3 chiều, khiến việc áp dụng gặp nhiều thách thức.
Giải thuật cây đa cực song song, một sản phẩm của nhóm khoa học máy tính tại Đại học Duke, USA, là sự kết hợp giữa giải thuật Barnes Hut và phương pháp đa cực nhanh Đây là một giải thuật phức tạp, đòi hỏi nhiều phép toán học phức tạp và gặp khó khăn trong việc lập trình trong không gian ba chiều.
MÔ PHỎNG N BODY VỚI ĐƠN GPU -
Mục đích mô phỏng N-Body trên GPU
Độ phức tạp của bài toán n body tăng cao khi số lượng body lớn, với một số giải thuật có độ phức tạp tính toán thấp hơn nhưng khó mô phỏng Giải thuật tương tác hạt hạt dễ mô phỏng nhưng có hiệu năng tính toán kém (O(N²)) Giải thuật Barnes Hut cải thiện độ phức tạp so với giải thuật tương tác hạt hạt, nhưng vẫn cao khi mô phỏng với số lượng n body lớn Hai giải thuật phân cực nhanh và cây đa cực song song có độ phức tạp tính toán thấp hơn, nhưng yêu cầu nhiều phép tính phức tạp và lập trình khó khăn trong không gian 3 chiều.
Trong giải thuật tương tác hạt-hạt, sự tương tác giữa các cặp phần tử diễn ra độc lập, cho phép lập trình viên thực hiện tính toán song song.
Các bộ xử lý đồ họa có thể lập trình được (GPU) đang trở thành lựa chọn phổ biến trong máy tính cá nhân nhờ khả năng hoạt động như bộ đồng xử lý cho các tác vụ tính toán GPU được tối ưu hóa cho các công việc tính toán, với hiệu suất thực hiện các phép toán số thực dấu chấm động vượt trội hơn so với CPU Đặc biệt, hiệu năng của GPU ngày càng được cải thiện nhanh chóng theo định luật Moore, trong khi tốc độ tăng trưởng hiệu năng của CPU đã chậm lại.
Trong chương này, chúng ta khám phá khả năng của GPU trong việc tăng tốc độ tính toán cho bài toán mô phỏng lực hấp dẫn N-Body, một vấn đề quan trọng trong vũ trụ học và thiên văn học N-Body giúp các nhà khoa học trực quan hóa và hiểu rõ hơn về hành vi của các thiên hà, hệ mặt trời mới hình thành, cũng như sự tiến hóa của vũ trụ Bài toán này yêu cầu khả năng tính toán lớn, với hiệu năng có thể lên đến O(N²) trong trường hợp xấu nhất Các mô phỏng lớn trên CPU thường mất nhiều thời gian để hoàn thành, do đó, việc tăng tốc độ xử lý sẽ giúp rút ngắn thời gian thực hiện và nâng cao hiệu quả tính toán.
Tính toán lực tương tác các cặp N- Body
Chúng ta sử dụng tiềm năng lực hấp dẫn để mô phỏng các cặp N-Body, với các vector được ký hiệu bằng phông chữ đậm trong không gian 3D Giả thiết có N body với tọa độ xi và vận tốc vi (1≤ i ≤ N), lực fij giữa body i và body j được tính theo công thức: fij = G * (mi * mj) / rij², trong đó mi và mj là khối lượng của body i và j, rij = xi - xj là vector khoảng cách giữa chúng, và G là hằng số hấp dẫn Độ lớn của lực cân bằng trọng lượng và khoảng cách, trong khi hướng của lực được xác định bởi vector đơn vị từ body i hướng tới body j, thể hiện bản chất của lực hấp dẫn.
Tổng lực Fi của body i, do các sự tương tác của nó với N 1 body khác, là - tổng của tất cả các lực tương tác thành phần:
Các body trong mô phỏng vật lý học thiên văn tương tác mà không bị ràng buộc lẫn nhau, dẫn đến tình huống không mong đợi Trong trường hợp này, các va chạm giữa các body thường bị loại trừ, điều này hợp lý khi các body đại diện cho các thiên hà có khả năng va chạm Để điều chỉnh cho trường hợp này, một sai số ε 2 > 0 được thêm vào và công thức được điều chỉnh tương ứng.
Lưu ý điều kiện i ≠ j không cần thiết trong tổng lực, bởi vì fii=0 khi ε 2 > 0
Hệ số sai số mô hình hóa sự tương tác giữa hai trọng lượng điểm Plummer cho thấy các khối lượng này được xem như các thiên hà hình cầu (Aarseth 2003, Dyer và Ip).
Hệ số sai số được sử dụng để giới hạn độ lớn thực của lực giữa các body, điều này rất quan trọng cho việc tính toán sự tương tác trong hệ thống Để đồng bộ thời gian, chúng ta cần tính gia tốc ai = Fi / mi nhằm cập nhật vị trí và vận tốc của body i, từ đó đơn giản hóa quá trình tính toán.
Phép lấy gần đúng Leapfrog-Verlet (Verlet 1967) được sử dụng để cập nhật vị trí và vận tốc trong các bài toán N Body do tính hiệu quả và độ chính xác cao của nó Việc lựa chọn giải thuật hợp nhất thường phụ thuộc vào đặc điểm tự nhiên của hệ thống nghiên cứu Thời gian tính toán của các phép lấy gần đúng này thường không quan trọng khi số lượng phần tử N tăng lên, mặc dù độ phức tạp tính toán O(N) có thể ảnh hưởng đến quá trình thực thi.
Sự thực thi CUDA của giải thuật tất cả các cặp N- Body
Giải thuật tất cả các cặp lực có thể được hiểu là việc tính toán từng phần tử fij trong ma trận N×N của tất cả các cặp lực Tổng lực Fi (hoặc gia tốc ai) trên body i được xác định từ tổng của các phần tử trên hàng i, với mỗi phần tử có thể được tính toán độc lập, tạo ra O(N²) phép toán song song Tuy nhiên, phương pháp này yêu cầu O(N²) ô nhớ và bị giới hạn bởi băng thông bộ nhớ Do đó, chúng ta nên tuần tự hóa quá trình tính toán để tái sử dụng dữ liệu, từ đó tối ưu hóa hiệu suất của các đơn vị toán học và giảm bớt yêu cầu về băng thông bộ nhớ.
Tile tính toán là một vùng hình vuông trong lưới với p hàng và p cột, trong đó 2p body được sử dụng để ước lượng tất cả p² sự tương tác Các body mô tả có thể được lưu trữ trong bộ nhớ dùng chung hoặc trong các thanh ghi Tổng hiệu ứng của các sự tương tác trong tile được thể hiện qua sự thay đổi giá trị từ p vector gia tốc Để tối ưu hóa việc sử dụng lại dữ liệu, tính toán cho tile được sắp xếp sao cho các sự tương tác trong mỗi hàng được ước lượng tuần tự, trong khi các hàng riêng biệt được ước lượng song song Hình 4.1 minh họa quy trình ước lượng và các đầu vào, đầu ra của bộ tính toán tile.
Hình 4.1 minh họa một tile tính toán, với bên trái hiển thị giá trị ước lượng và bên phải liệt kê các đầu vào cần thiết cùng với các đầu ra đã thực hiện Trong tile này, p2 tương tác được tính toán một cách chính xác.
4.3.1 Tính toán lực body – body
Sự tương tác giữa hai body được mô tả qua toàn bộ quá trình tính toán, trong đó mã nguồn tính toán lực tác động lên body i từ body j và cập nhật gia tốc ai của body i Đoạn mã này bao gồm 20 thao tác dấu chấm động, bao gồm phép cộng, phép nhân, gọi hàm sqrtf( ), và phép chia hoặc nghịch đảo Đoạn mã 1 thể hiện cách cập nhật gia tốc của một body dựa trên sự tương tác với một body khác.
device float3 bodyBodyInteraction(float4 bi, float4 bj, float3 ai)
// r_ij [3 FLOPS] r.x = bj.x - bi.x; r.y = bj.y - bi.y; r.z = bj.z - bi.z;
// distSqr = dot(r_ij, r_ij) + EPS^2 [6 FLOPS] float distSqr = r.x * r.x + r.y * r.y + r.z * r.z + EPS2;
// invDistCube =1/distSqr^(3/2) [4 FLOPS (2 mul, 1 sqrt, 1 inv)] float distSixth = distSqr * distSqr * distSqr; float invDistCube = 1.0f/sqrtf(distSixth);
// s = m_j * invDistCube [1 FLOP] float s = bj.w * invDistCube;
// a_i = a_i + s * r_ij [6 FLOPS] ai.x += r.x * s; ai.y += r.y * s; ai.z += r.z * s; return ai;
Chúng ta sử dụng kiểu dữ liệu float4 trong CUDA để mô tả các body và gia tốc lưu trữ trong bộ nhớ của GPU Trọng lượng của mỗi body được lưu trong biến w với kiểu float4 Việc sử dụng float4 thay vì float3 giúp truy cập bộ nhớ liền nhau từ chuỗi dữ liệu trong bộ nhớ thiết bị, từ đó nâng cao hiệu quả yêu cầu và thao tác bộ nhớ Các vector ba chiều (3D) được lưu trong các biến địa phương dưới dạng float3, do vấn đề không gian thanh ghi và vì chúng được truy cập lại.
Một tile được xử lý bởi p thread, mỗi thread thực hiện cùng một trình tự trên các dữ liệu khác nhau Mỗi thread cập nhật gia tốc của một body dựa trên sự tương tác với p body khác Chúng ta nạp p body từ bộ nhớ GPU vào bộ nhớ chia sẻ cho một thread block trong mô hình CUDA Mỗi thread trong block tương ứng với p sự tương tác liên tiếp, và kết quả tính toán là gia tốc p được cập nhật Đoạn mã mô tả quá trình tính toán tile, với tham số đầu ra myPosition lưu giữ vị trí của body trong quá trình thực thi, và mảng shPosition là mảng body trong bộ nhớ dùng chung Các thread thực hiện chức năng body theo cách song song, mỗi thread tính toán gia tốc của body riêng lẻ dựa trên tương tác với p body khác.
device float3 tile_calculation(float4 myPosition, float3 accel){ int i; extern shared float4[ ] shPosition; for (i = 0; i < blockDim.x; i++) { accel = bodyBodyInteraction(myPosition, shPosition[i], accel);
Kiến trúc GPU G80 cho phép nhiều thread đọc dữ liệu từ một địa chỉ bộ nhớ dùng chung mà không gặp phải xung đột (bank conflicts), điều này giúp tối ưu hóa quá trình tính toán các sự tương tác.
4.3.3 Xếp nhóm các tile vào trong các Thread Block
Một thread block được định nghĩa với p thread thực thi tuần tự, xử lý một số lượng tile nhất định Các tile được kích thước cân bằng để tối ưu hóa tính song song và dữ liệu dùng lại Mức độ song song cần đủ lớn để các warp có thể xen kẽ, giúp che giấu các tương tác Số lượng dữ liệu dùng lại tăng theo số cột, và các tham số này ảnh hưởng đến kích thước chuyển đổi từ thiết bị nhớ vào bộ nhớ dùng chung Kích thước tile cũng xác định yêu cầu về dung lượng thanh ghi và bộ nhớ dùng chung Trong thực thi, các tile hình vuông có kích thước p×p được sử dụng Trước khi thực hiện, mỗi thread đưa một body vào bộ nhớ dùng chung và sau đó các thread được đồng bộ hóa, bắt đầu với p body liên tiếp trong bộ nhớ dùng chung.
Hình 4.2 minh họa một thread block thực hiện mã cho các tile, với thời gian trải theo chiều ngang và tính song song theo chiều dọc Các đường kẻ đậm xác định ranh giới giữa các tile tính toán, cho thấy nơi bộ nhớ dùng chung được nạp và hàng rào đồng bộ hóa được thực hiện Trong mỗi thread block, có N/p tile, với p thread chịu trách nhiệm tính toán lực cho p body, mỗi thread tương ứng với một body Mỗi thread thực hiện tất cả N tương tác cho một body.
The `calculate_forces` kernel in CUDA utilizes shared memory to optimize the computation of forces in a parallel processing environment It begins by defining shared memory for storing positions and initializes global pointers for the input data Each thread calculates its global thread ID and retrieves its corresponding position The kernel then iterates through the data in tiles, loading positions into shared memory for efficient access This approach enhances performance in simulations involving multiple particles by minimizing global memory access and maximizing parallel processing capabilities.
syncthreads(); acc = tile_calculation(myPosition, acc);
// Luu ket qua trong bo nho toan cuc cho buoc tuong tac float4 acc4 = {acc.x, acc.y, acc.z, 0.0f}; globalA[gtid] = acc4;
Hàm calculate_forces( ) sử dụng các con trỏ từ thiết bị nhớ toàn cục để truy cập các vị trí devX và gia tốc devA của các body, và chúng được gán với các con trỏ địa phương thông qua việc chuyển đổi kiểu để có thể được đánh chỉ số như mảng Quá trình duyệt qua các tile yêu cầu hai điểm đồng bộ hóa: điểm đồng bộ hóa đầu tiên đảm bảo rằng tất cả vị trí vùng nhớ dùng chung đã được lưu trữ trước khi thực hiện tính toán hấp dẫn, trong khi điểm đồng bộ hóa thứ hai đảm bảo rằng tất cả các thread hoàn tất tính toán hấp dẫn của chúng trước khi chuyển sang tile tiếp theo Nếu không có điểm đồng bộ hóa thứ hai, các thread có thể kết thúc phần tính toán của chúng trong khi bộ nhớ dùng chung vẫn đang được các thread khác đọc, dẫn đến việc ghi đè không mong muốn.
4.3.4 Định nghĩa một Grid của các Thread Block
Kernel lập trình trong phần trên (code 3) tính toán gia tốc của p body trong hệ thống, dựa trên các tương tác với tất cả N body Chương trình được triển khai trên một grid của các thread block để tính toán gia tốc cho tất cả N body Với p thread cho mỗi block và một thread cho mỗi body, số thread block cần thiết là N/p, do đó, chúng ta định nghĩa grid 1 chiều có kích thước N/p Kết quả là tổng N thread thực hiện tính toán N lực, dẫn đến tổng cộng N² tương tác.
Hình 4.3 minh họa cách tính toán toàn bộ grid cho các sự tương tác, với chiều dọc thể hiện sự song song của grid một chiều gồm N/p thread block, mỗi thread block độc lập với p thread Chiều ngang cho thấy quá trình xử lý tuần tự của N lực tính toán trong từng thread Mỗi thread block thực hiện việc nạp lại bộ nhớ chia sẻ trong suốt p bước tới p vị trí dữ liệu chia sẻ.
Hình 4.3 Lưới Thread Block để tính toán tất cả N 2 lực Ở đây có 4 thread block với 4 thread mỗi chúng
Môi trường thử nghiệm bài toán
Sau khi hoàn thành việc phát triển thuật toán mô phỏng bài toán N-Body trên hệ thống đơn GPU, chúng tôi tiến hành thiết lập môi trường thử nghiệm cho bài toán này.
Cấu hình phần cứng gồm:
CPU :Intel® Core ™ 2 Quad CPU Q 8400
Total amount of global memory : 939.261.952 bytes ( ≈ 1GB) Number of multiprocessors : 30
Total amount of constant memory : 65536 bytes
Total amount of shared memory per block : 16384 bytes
Total number of registers available per block : 16384
Maximum number of threads per block : 512
Maximum sizes of each dimension of a block: 512 x 512 x 64
Maximum sizes of each dimension of a grid : 65535 x 65535 x 1
Concurrent copy and execution : Yes
Run time limit on kernels : No
Support host page-locked memory mapping : Yes
Compute mode : Default (multiple host threads can use this device simultaneously)
Cách thử nghiệm bài toán N Body trên hệ thống -
Sau khi cài đặt bài toán mô phỏng N-Body, chúng ta tiến hành triển khai trên môi trường thử nghiệm đã được mô tả Để chạy chương trình, hãy truy cập vào thư mục chứa bài toán nbody đã được biên dịch thông qua makefile, sau đó nhập dòng lệnh cần thiết.
/nbody -benchmark n= p= q= i= - - - -
Benchmark là phương pháp đo hiệu suất hệ thống thông qua phần mềm benchmark, cho ra kết quả bao gồm tổng thời gian, thời gian trung bình và số lượng tương tác giữa các body mỗi giây, cùng với các mức GFLOP/s Tham số n= được sử dụng để thiết lập số lượng body cần mô phỏng trong bài toán.
-p=: thiết lập độ rộng của tile được sử dụng trong mô phỏng, ngầm định p%6
-q=: thiết lập chiều cao của tile được sử dụng trong mô phỏng, ngầm định q=1
-i=: thiết lập số tương tác chạy trong chế độ benchmark Ngầm định i0
Chú ý: Ở đây p, q là chiều rộng và chiều cao của 1 tile tính toán, điều kiện là pxq 6144, hiệu năng hệ thống duy trì ở mức cao, vượt quá 200 GFlops.
Khi số lượng body tăng lên, hiệu năng của hệ thống cũng được cải thiện đáng kể Hiệu năng của GPU vượt trội hơn so với CPU, với tỷ lệ chênh lệch từ hàng chục đến hàng trăm lần (104→608 lần).
Sự thực thi đầu tiên đạt 271 gigaflops cho 16.384 body, một kết quả ấn tượng Tuy nhiên, vẫn còn nhiều tối ưu hóa có thể áp dụng để nâng cao hiệu suất thực hiện.
4.7.1 Gia tăng hiệu năng với lặp không cuộn (loop unrolling)
Cải tiến đầu tiên là việc áp dụng lặp không cuộn, trong đó chúng ta thay thế một tương tác đơn trong vòng lặp với từ 2 đến 32 lần gọi, nhằm giảm thiểu sự lặp lại ở đầu vòng.
Dưới đây là biểu đồ hiệu năng kiểm thử trên GPU, với số lượng body được kiểm thử là 1024, 4096 và 16.384 body, và số tương tác mỗi body là 100
Bảng 4.3 Hiệu năng với Unroll=1, 2, 4
Một biểu đồ về hiệu năng của các nhân tố mở vòng nhỏ được đưa ra trong hình 4.7
Hình 4.7 minh họa sự cải thiện hiệu năng khi áp dụng kỹ thuật mở lặp Đồ thị thể hiện sự biến đổi hiệu suất khi số lần unroll trong vòng lặp được tăng lên 1, 2 và 4 lần, tương ứng với các mô phỏng có 1024, 4096 và 16.384 body.
Các phương pháp trước đây sử dụng GPU mô phỏng N-Body
Bài toán N-Body đã được nghiên cứu từ lâu trong lĩnh vực tính toán, với những giải thuật phân cấp và mắt lưới được giới thiệu vào thập kỷ 80, giúp giảm độ phức tạp tính toán xuống còn O(N²) Tính song song của bài toán cũng đã được khai thác khi xuất hiện các máy tính song song Hiện nay, hiệu năng cao đã được đạt được nhờ vào việc sử dụng phần cứng GPU, hạn chế việc nhắc lại các nghiên cứu trước đây.
Vào năm 2004, ứng dụng N Body đã được xây dựng trên GPU bằng cách sử dụng Cg và OpenGL (Nyland, Harris và Prins 2004) Cg đã cho thấy sức mạnh vượt trội của ngôn ngữ lập trình GPU, nhưng cũng gặp phải một số hạn chế trong môi trường đồ họa, như dữ liệu chỉ có thể đọc hoặc ghi Để khắc phục, một bộ đệm kép đã được áp dụng Tất cả các tính toán bắt đầu bằng việc vẽ hình chữ nhật, với giá trị điểm ảnh được tính toán qua một chương trình bị che giấu, yêu cầu O(N²) bộ nhớ Do sự phức tạp của các thuật toán trong đồ họa API, chúng tôi đã thực hiện tính toán lực thô cho tất cả các cặp gia tốc trong một kết cấu lớn hơn, sau đó giảm tổng song song các vector gia tốc toàn phần Tuy nhiên, việc giảm tổng này bị hạn chế bởi băng thông và thiếu bộ nhớ dùng chung trên chip, khiến kích thước kết cấu tối đa của GPU chỉ cho phép tối đa 2048 body Việc sử dụng phương pháp ngoài lõi đã giúp vượt qua giới hạn này.
Một nhóm nhà nghiên cứu tại trường đại học Stanford (Elsen et al 2006) đã phát triển một giải pháp tương tự để mô tả bài toán này, sử dụng ngôn ngữ lập trình BrookGPU và dữ liệu hiệu năng từ card đồ họa ATI X1900XTX GPU Họ kết luận rằng việc mở vòng lặp cải thiện đáng kể hiệu năng, nhưng đạt hiệu năng tốt với N