D · GPU engineering
Viết kernel với tư duy dữ liệu và tính toán song song
Cách lập trình song song trên GPU bằng CUDA hoặc Triton để chia khối dữ liệu, tận dụng bộ nhớ đệm trên chip và tối ưu băng thông.
1Định nghĩa
Lập trình kernel bằng CUDA hoặc Triton là việc viết các hàm tính toán chạy trực tiếp trên hàng nghìn nhân của GPU khi các toán tử có sẵn của framework chưa đủ nhanh hoặc tốn quá nhiều lượt đọc/ghi bộ nhớ.
Trong khi CUDA cho phép điều khiển chi tiết từng luồng (thread) và khối luồng (thread block) ở mức C++, Triton giúp kỹ sư viết mã theo từng khối mảng (tile/block) bằng Python và tự động hóa phần lớn việc sắp xếp bộ nhớ. Dù dùng công cụ nào, bài toán cốt lõi vẫn là chia tensor thành các ô vừa với bộ nhớ đệm trên chip (SRAM/shared memory), tính toán song song và hạn chế tối đa số lần truy cập bộ nhớ HBM.
Ví dụ đời thường: Viết kernel bằng CUDA/Triton giống như việc chia một bức tường lớn thành từng ô gạch để hàng trăm người thợ cùng sơn một lúc. Thay vì mỗi người thợ cứ quét một nét cọ lại phải chạy ra tận kho chính (HBM) lấy sơn, mỗi nhóm thợ xách luôn một xô sơn nhỏ đặt ngay cạnh giàn giáo của mình (SRAM trên chip) để sơn liền mạch hết cả ô tường rồi mới đổi chỗ.
2Luồng
- Định nghĩa phép toán reference
Có shapes và dtype yêu cầu.
- Chia dữ liệu thành tiles
Gán công việc và chọn layout.
- Tính trong kernel
Đọc, tái dùng và ghi dữ liệu.
- Kiểm tra và profile
So sai số, race và latency nhiều shapes.
Mã Mermaid
flowchart TD
step1["Định nghĩa phép toán reference"]
step2["Chia dữ liệu thành tiles"]
step3["Tính trong kernel"]
step4["Kiểm tra và profile"]
step1 --> step2
step2 --> step3
step3 --> step4 3Giải pháp
Bắt đầu từ một kernel đúng và một baseline. Tune tile sizes, vectorization và tài nguyên gần compute dựa profiler.
Tránh tối ưu một shape rồi mặc định các shape khác tốt. Đọc đồng thời, synchronization và lifetime sai có thể tạo lỗi chỉ xuất hiện dưới tải.
4Profiling
- Latency và memory access
Đo runtime theo shape; tìm giao dịch bộ nhớ dư và register spills.
- Correctness
So reference ở nhiều kích thước, nhất là dimensions không chia hết tile.
Mẹo đo lường: ghim số liệu trên workload thật, ghi cả p50/p95/p99 thay vì chỉ trung bình, và luôn ghi lại điều kiện chạy (batch, cache, đồng thời, phần cứng) trước và sau khi tối ưu. Số đo thiếu điều kiện chạy thì không so sánh được.
5Ví dụ
Normalization của vector
Một bài kernel nhỏ có thể bắt đầu bằng tính trung bình bình phương rồi scale từng phần tử.
Ma trận kích thước lẻ
Cần mask truy cập ngoài biên; tốc độ tốt trên shape tròn không bảo đảm đúng ở shape này.
6Thuật ngữ
- Compute Unified Device Architecture (CUDA)
- Nền tảng lập trình và mô hình thực thi tính toán trên thiết bị NVIDIA.
- Thread và thread block
- Đơn vị công việc và nhóm threads có thể phối hợp theo mô hình thực thi của thiết bị.
- Coalesced memory access
- Cách nhiều threads đọc các địa chỉ thuận lợi để phần cứng gộp giao dịch bộ nhớ.
Glossary (12)
- Graphics Processing Unit
- Bộ xử lý đồ họa, thường dùng cho phép tính tensor song song.
- Data type
- Kiểu dữ liệu của tensor, quyết định cách biểu diễn số.
- Tensor
- Mảng số nhiều chiều, như một vector, ma trận hoặc nhóm ma trận.
- Vector
- Danh sách các số biểu diễn một token hoặc đặc trưng.
- Kernel
- Hàm tính toán chạy trên thiết bị; thường xử lý nhiều phần tử song song.
- Runtime
- Phần mềm quản lý việc thực thi, buffers và phụ thuộc giữa phép toán.
- Mask
- Quy tắc vị trí nào được nhìn nhau hoặc được tính vào loss.
- Latency
- Thời gian chờ để nhận một kết quả hoặc một bước kết quả.
- Overhead
- Chi phí phụ như điều phối, chuyển đổi hoặc phát lệnh ngoài phép tính chính.
- Host
- Phần chương trình điều khiển thiết bị, thường chạy trên bộ xử lý trung tâm.
- Baseline
- Cấu hình hoặc kết quả gốc dùng làm mốc so sánh.
- Tensor shape
- Kích thước các chiều của tensor; ảnh hưởng layout, kernel và memory.