Tóm tắt
Giới thiệu
- Nhân ma trận là một thành phần thiết yếu trong các mạng nơ-ron hiện đại
- NumPy đạt hiệu năng cao bằng cách sử dụng các thư viện BLAS bên ngoài
- Bài viết này giải thích cách triển khai phép nhân ma trận hiệu năng cao theo cách đơn giản, có tính di động và có thể mở rộng
Hiệu năng của NumPy
- NumPy sử dụng OpenBLAS trên CPU AMD
- Hiệu năng được đo bằng FLOP/s
- Đo hiệu năng đơn luồng và đa luồng của NumPy trên CPU Ryzen 7 7700
Giới hạn lý thuyết
- Giải thích cấu trúc phân cấp bộ nhớ của CPU và các mở rộng SIMD
- Về lý thuyết có thể đạt 163 GFLOPS ở đơn luồng và 1203 GFLOPS ở đa luồng
Triển khai đơn giản
- Giải thích thuật toán nhân ma trận cơ bản và đo hiệu năng của cách triển khai đơn giản
- Cách triển khai đơn giản đạt 2.7 GFLOPS
Kernel
- Giải thích cách giải bài toán bằng cách chia phép nhân ma trận thành các bài toán con nhỏ
- Tối ưu hóa kernel bằng các lệnh SIMD
- Đạt 147 GFLOPS với kernel 16x6
Masking và packing
- Giải thích cách xử lý các trường hợp biên để hỗ trợ kích thước ma trận tùy ý
- Tối ưu hóa hiệu năng bằng masking và packing
- Cách triển khai mới đạt 56 GFLOPS
Caching
- Giải thích hệ thống bộ nhớ của CPU cache
- Tối ưu hóa việc tái sử dụng dữ liệu và quản lý cache bằng cách tận dụng cache
Ý kiến của GN⁺
- Bài viết này rất giàu tính giáo dục khi giải thích từng bước cách triển khai phép nhân ma trận hiệu năng cao
- Có thể học được các phương pháp tối ưu hóa bằng lệnh SIMD và CPU cache
- Hữu ích để hiểu cách hoạt động bên trong của các thư viện như NumPy
- Các dự án khác có chức năng tương tự gồm Intel MKL, OpenBLAS, v.v.
- Khi áp dụng công nghệ mới hoặc mã nguồn mở, cần cân nhắc giữa hiệu năng và tính di động
1 bình luận
Ý kiến Hacker News
Phần lớn phần mềm chưa được tối ưu, nên vẫn còn nhiều dư địa để cải thiện hiệu năng
Các bài báo được tham chiếu trong repo BLIS là tài liệu có thẩm quyền để hiểu chủ đề này
Lệnh SIMD không cần thiết cho việc vector hóa micro-kernel
Hầu hết các mẫu lập trình không được chuyên biệt hoàn toàn cho phần cứng nên đang bỏ lỡ rất nhiều hiệu năng
Đáng khen ở chỗ giúp việc lặp lại benchmark trở nên dễ dàng
matmul.cmất 1,41 giây khi biên dịch bằnggcc -O3, 1,47 giây khi biên dịch bằngclang -O2, còn NumPy mất 1,07 giâyNghi ngờ liệu phần triển khai của NumPy có thực sự dùng đa luồng hay không
Tò mò vì sao nó lại nhanh hơn OpenBLAS
So sánh một bên là Python, bên kia là C thì không công bằng
Sự kém hiệu quả trong việc tạo mask khiến người ta bận tâm
Đặt câu hỏi về tính thực tiễn của việc đa luồng hóa chính phép nhân ma trận
Nhắc đến tinyBLAS của jart