Facebook mã nguồn mở Cinder, một nhánh của CPython được Instagram sử dụng

Facebook đã xuất bản mã nguồn của Project Cinder, một nhánh của CPython 3.8.5, triển khai tham chiếu chính của ngôn ngữ lập trình Python. Cinder được sử dụng trong cơ sở hạ tầng sản xuất của Facebook để hỗ trợ Instagram và bao gồm các tính năng tối ưu hóa để cải thiện hiệu suất.

Mã được xuất bản để thảo luận về khả năng chuyển các tối ưu hóa đã chuẩn bị sang khung CPython chính và trợ giúp các dự án khác liên quan đến việc cải thiện hiệu suất CPython. Facebook không có ý định hỗ trợ Cinder dưới dạng một dự án nguồn mở riêng biệt và mã được trình bày dưới dạng mà nó được sử dụng trong cơ sở hạ tầng của công ty mà không cần phải tổng hợp và tài liệu bổ sung. Họ cũng không cố gắng quảng bá Cinder như một giải pháp thay thế cho CPython - mục tiêu phát triển chính là mong muốn cải thiện chính CPython.

Mã Cinder được đánh giá là khá đáng tin cậy và đã được thử nghiệm trong môi trường sản xuất, nhưng nếu xác định được vấn đề, bạn sẽ phải tự giải quyết chúng vì Facebook không đảm bảo rằng họ sẽ phản hồi các thông báo lỗi bên ngoài và yêu cầu kéo. Đồng thời, Facebook không loại trừ sự hợp tác mang tính xây dựng với cộng đồng và sẵn sàng thảo luận các ý tưởng về cách làm cho Cinder nhanh hơn nữa hoặc cách tăng tốc độ chuyển các thay đổi đã chuẩn bị sang phần chính của CPython.

Các tối ưu hóa chính được triển khai trong Cinder:

  • Bộ nhớ đệm nội tuyến của mã byte (“mã byte bóng”). Bản chất của phương pháp này là xác định các tình huống trong đó một opcode điển hình được thực thi có thể được tối ưu hóa và thay thế linh hoạt một opcode đó bằng các tùy chọn chuyên biệt nhanh hơn (ví dụ: thay thế các hàm được gọi thường xuyên).
  • Đánh giá coroutine háo hức. Đối với các lệnh gọi hàm không đồng bộ được xử lý ngay lập tức (chờ đợi không dẫn đến chờ đợi và hàm đạt đến câu lệnh return sớm hơn), kết quả của các hàm đó được thay thế trực tiếp mà không cần tạo coroutine hoặc liên quan đến vòng lặp sự kiện. Trong mã Facebook sử dụng nhiều async/await, việc tối ưu hóa mang lại tốc độ tăng khoảng 5%.
  • Biên dịch JIT có chọn lọc ở cấp độ các phương thức và hàm riêng lẻ (phương thức tại một thời điểm). Được bật thông qua tùy chọn “-X jit” hoặc biến môi trường PYTHONJIT=1 và cho phép bạn tăng tốc độ thực hiện nhiều bài kiểm tra hiệu suất lên 1.5-4 lần. Vì quá trình biên dịch JIT chỉ phù hợp với các hàm được thực thi thường xuyên nên không nên sử dụng nó cho các hàm hiếm khi được sử dụng vì chi phí biên dịch của chúng chỉ có thể làm chậm quá trình thực thi chương trình.

    Thông qua tùy chọn “-X jit-list-file=/path/to/jitlist.txt” hoặc biến môi trường “PYTHONJITLISTFILE=/path/to/jitlist.txt”, bạn có thể chỉ định một tệp có danh sách các hàm phù hợp với JIT có thể được sử dụng (định dạng đường dẫn .to.module:funcname hoặc path.to.module:ClassName.method_name). Danh sách các chức năng cần kích hoạt JIT có thể được xác định dựa trên kết quả lập hồ sơ. Trong tương lai, dự kiến ​​sẽ có hỗ trợ biên dịch JIT động dựa trên phân tích nội bộ về tần suất của các lệnh gọi hàm, nhưng có tính đến các chi tiết cụ thể của quá trình khởi chạy trên Instagram, quá trình biên dịch JIT cũng phù hợp với Facebook ở giai đoạn đầu.

    Trước tiên, JIT chuyển đổi mã byte Python thành biểu diễn trung gian cấp cao (HIR), khá gần với mã byte Python, nhưng được thiết kế để sử dụng máy ảo dựa trên đăng ký thay vì máy ảo dựa trên ngăn xếp và cũng sử dụng thông tin loại và các tính năng bổ sung. các chi tiết quan trọng về hiệu suất (chẳng hạn như tính tham chiếu). Sau đó, HIR được chuyển đổi sang dạng SSA (gán đơn tĩnh) và trải qua các bước tối ưu hóa có tính đến kết quả đếm tham chiếu và dữ liệu tiêu thụ bộ nhớ. Kết quả là một biểu diễn trung gian cấp thấp (LIR) được tạo ra, gần với hợp ngữ. Sau một giai đoạn tối ưu hóa dựa trên LIR khác, các hướng dẫn lắp ráp được tạo bằng thư viện asmjit.

  • Chế độ nghiêm ngặt cho các mô-đun. Chức năng này bao gồm ba thành phần: Loại StrictModule. Một bộ phân tích tĩnh có thể xác định rằng việc thực thi một mô-đun không ảnh hưởng đến mã bên ngoài mô-đun đó. Trình tải mô-đun xác định rằng các mô-đun đang ở chế độ nghiêm ngặt (mã chỉ định “nhập __strict__”), kiểm tra sự vắng mặt của giao điểm với các mô-đun khác và tải các mô-đun nghiêm ngặt vào sys.modules dưới dạng đối tượng StrictModule.
  • Static Python là một trình biên dịch mã byte thử nghiệm sử dụng chú thích kiểu để tạo mã byte dành riêng cho từng loại chạy nhanh hơn nhờ biên dịch JIT. Trong một số thử nghiệm, sự kết hợp giữa Static Python và JIT cho thấy sự cải thiện hiệu suất lên tới 7 lần so với CPython tiêu chuẩn. Trong nhiều trường hợp, kết quả ước tính gần giống với việc sử dụng trình biên dịch MyPyC và Cython.

Nguồn: opennet.ru

Thêm một lời nhận xét