4 điểm bởi GN⁺ 2024-10-19 | 1 bình luận | Chia sẻ qua WhatsApp

Tận dụng tính đồng thời và song song của Go

  • Giới thiệu một dự án nhằm cải thiện năng lực tính toán số bằng cách tận dụng tính đồng thời và song song của Go.
  • Có thể thực hiện tính toán song song ở cấp độ phần cứng bằng cách sử dụng các lệnh SIMD (Same Instruction Multiple Data).
  • Trình biên dịch của Go không tận dụng SIMD, và do không tìm được gói SIMD đa dụng phù hợp nên tác giả quyết định tự phát triển một gói.

Ngôn ngữ assembly Plan9

  • Go sử dụng ngôn ngữ assembly riêng là Plan9, được dùng bằng cách điều chỉnh đôi chút các lệnh và thanh ghi của từng nền tảng cụ thể.
  • x86 Plan9 và ARM Plan9 khác nhau.
  • Giải thích cách sử dụng cơ bản thông qua các ví dụ đơn giản của Plan9.

Ví dụ Plan9

  • Giải thích cách khai báo và sử dụng hàm cơ bản của Plan9 thông qua các tệp AddInts_amd64.smain.go.
  • Mô tả cách lưu tham số hàm và giá trị trả về trên stack theo quy ước gọi hàm của Go.

Kế hoạch thiết kế gói

  • Thiết kế một gói cung cấp lớp trừu tượng mỏng cho các tác vụ SIMD về số học và phép toán bit.
  • Tạo gói nội bộ chứa các triển khai Plan9 theo từng kiến trúc, rồi thiết lập chúng thông qua hàm khởi tạo.

Ví dụ SIMD

  • Giải thích cách dùng SIMD thông qua ví dụ về các hàm Plan9 SIMD trên x86.
  • Trình bày cách kiểm tra hỗ trợ SSE và thực hiện phép cộng float32 thông qua các tệp Supported_amd64.sAddFloat32_amd64.s.

Hiệu năng và tương lai

  • Biểu đồ cho thấy chênh lệch hiệu năng giữa triển khai phần mềm Go và triển khai Plan9 SIMD, xác nhận mức tăng tốc khoảng 200-450%.
  • Tác giả hy vọng ghi chú này sẽ truyền cảm hứng cho các dự án sử dụng Plan9 và SIMD.

# Tổng hợp của GN⁺

  • Bài viết này giới thiệu cách tận dụng tính đồng thời và song song của Go để tối đa hóa hiệu năng.
  • Giải thích cách thực hiện tính toán song song ở cấp độ phần cứng bằng ngôn ngữ assembly Plan9 và các lệnh SIMD.
  • Bài viết gợi mở cho các lập trình viên Go về khả năng ứng dụng Plan9 và SIMD, đồng thời có thể hữu ích khi khám phá các cách tiếp cận mới để cải thiện hiệu năng.
  • Các dự án có chức năng tương tự được gợi ý gồm thư viện hỗ trợ SIMD của Rust hoặc các thư viện liên quan đến SIMD trong C++.

1 bình luận

 
GN⁺ 2024-10-19
Ý kiến trên Hacker News
  • Giải thích về NOSPLIT: đây là cú pháp đặc trưng trong assembly Go để mô tả kích thước frame và kích thước đối số

    • Kích thước frame và kích thước đối số được ngăn cách bằng -, đây không phải phép trừ toán học
    • Công cụ go vet sẽ kiểm tra xem kích thước đối số có chính xác hay không
  • Ý kiến về cách diễn giải của LLM (mô hình ngôn ngữ lớn): có thể có hiểu lầm trong việc diễn giải mã

    • Có ý kiến cho rằng nếu tác giả thẳng thắn thừa nhận thì sẽ có ích cho việc học
  • Đề cập đến ngôn ngữ assembly nội bộ Plan9 của Go: Go sử dụng ngôn ngữ assembly riêng của mình

    • Trên amd64, int là 64 bit, và nếu dùng int32 thì sẽ được căn chỉnh theo word trong danh sách đối số
    • NOSPLIT được định nghĩa trong textflag.h và chỉ có hiệu lực trong runtime
  • Giải thích của Rob Pike về thiết kế assembly của Go: tạo ra một ngôn ngữ assembly chung để có thể giao tiếp với máy mà không cần học cú pháp mới

    • Có thể tự động tạo assembler bằng cách dùng tài liệu mô tả cho kiến trúc mới làm đầu vào
  • Ý kiến về việc dùng hàm cho phép toán SIMD: cần có hàm có thể thực hiện phép toán SIMD trên slice

    • Khi cộng hai slice, có thể dùng SIMD để xử lý song song thay vì vòng lặp for
  • Triết lý thiết kế của trình biên dịch Go: hướng tới trình biên dịch đơn giản và nhanh thay vì phức tạp

    • Hỗ trợ x64 cơ bản bao gồm SSE và SSE2, ưu tiên sự đơn giản hơn là hiệu năng
  • Ý kiến về việc dùng GPU cho phép toán SIMD: GPU vượt trội trong xử lý song song và phép toán ma trận nên có thể phù hợp hơn cho SIMD

    • Tuy nhiên, trong Go có thể không phù hợp do thiếu các gói GPU và cộng đồng hỗ trợ