2 điểm bởi GN⁺ 2023-07-01 | 2 bình luận | Chia sẻ qua WhatsApp
  • Dự án Zig đặt mục tiêu loại bỏ hoàn toàn các phụ thuộc vào thư viện LLVM, Clang, LLD khỏi tệp thực thi zig chính
  • Các việc còn lại được chia thành loại bỏ LLD, loại bỏ các lời gọi LLVM API, tiến độ của các backend C/x86/wasm/aarch64, loại bỏ việc dùng tiền xử lý và các lệnh con phụ thuộc Clang, triển khai thay thế zig ar, v.v.
  • Backend LLVM hiện đã xuất được tệp .bc, nhưng trình biên dịch Zig sẽ không còn có chức năng biên dịch .bc thành tệp object; trong trường hợp này cần cài đặt Clang riêng
  • Các hiệu quả kỳ vọng gồm đơn giản hóa việc build từ mã nguồn và bootstrap, tránh các vấn đề liên quan LLVM/Clang/LLD của các bản phân phối Linux và Homebrew, giảm kích thước binary từ khoảng 150 MiB → 5 MiB
  • Zig đưa ra định hướng tự triển khai các optimization pass riêng và có thể thu hút các dự án nghiên cứu như alive2, cũng như đóng góp trực tiếp từ các nhà sản xuất chip Intel, ARM, RISC-V

Các phụ thuộc muốn loại bỏ khỏi tệp thực thi Zig

  • Mục tiêu của issue này là loại bỏ hoàn toàn các thư viện LLVM, Clang, LLD khỏi dự án Zig
  • Các điểm kết nối còn lại được phân loại thành các mảng LLD, LLVM, Clang và zig ar

Việc còn lại liên quan đến LLD

Việc còn lại liên quan đến LLVM

Việc còn lại liên quan đến Clang

Các ràng buộc trong xử lý zig ar và tệp .bc

  • zig ar: a drop-in llvm-ar replacement #9828: Còn việc biến zig ar thành bản thay thế tương thích trực tiếp cho llvm-ar
  • Backend LLVM hiện đã xuất được tệp .bc, nhưng trình biên dịch Zig sẽ không còn có chức năng biên dịch tệp .bc thành tệp object
  • Để xử lý use case này, cần cài đặt Clang riêng

Những thay đổi kỳ vọng từ việc loại bỏ phụ thuộc

  • Tất cả lỗi phía Zig sẽ nằm trong phạm vi trách nhiệm của dự án Zig
  • Quá trình build trình biên dịch từ mã nguồn và bootstrap sẽ đơn giản hơn; trên hệ thống host chỉ cần có trình biên dịch C
  • Các bản phân phối Linux và trình quản lý gói như Homebrew sẽ không còn phải xử lý các vấn đề liên quan đến LLVM, Clang, LLD
  • Kích thước binary của trình biên dịch Zig giảm từ khoảng 150 MiB xuống 5 MiB
  • Tốc độ biên dịch có thể nhanh hơn theo cấp nhiều bậc độ lớn
  • Zig có thể tự triển khai các optimization pass riêng để đẩy trình độ điện toán lên mức mới nhất
  • Có thể thu hút các dự án nghiên cứu như alive2
  • Có thể khuyến khích đóng góp trực tiếp từ các bên liên quan muốn có machine code tốt hơn trên CPU của họ, như các nhà sản xuất chip Intel, ARM, RISC-V

2 bình luận

 
alstjr7375 2023-07-02

Liệu có thể đạt được mức tối ưu hóa hay hỗ trợ nền tảng như LLVM không..

 
GN⁺ 2023-07-01
Ý kiến trên Hacker News
  • Andrew vốn là người cực kỳ sắc bén nên một khi đã tuyên bố đó là mục tiêu thì có lẽ cả đội cuối cùng sẽ làm được
    Tuy vậy, từ góc nhìn của người không hiểu rõ khó khăn của Zig liên quan đến LLVM, quyết định này trông như đang chuyển năng lực của đội sang các công cụ phụ trợ kiểu binutils hơn là bản thân Zig
    Khi chỉ nhìn tiêu đề thì tôi còn tưởng họ định bỏ luôn trình biên dịch, và với một dự án như Zig thì việc giữ LLVM dường như vẫn mang lại nhiều lợi ích
    Dù vậy, ý tưởng viết lại nhiều đoạn mã trong LLVM bằng Zig thay vì C++ vẫn khá ngầu và đầy tham vọng. Cũng có thể xem là tham vọng ngang với nỗ lực của Lattner khi tạo ra LLVM
    Nhưng những đoạn mã vô tình rơi vào độ phức tạp thời gian bậc hai thì Zig cũng sẽ khó tránh khỏi nếu một ngày nó trở nên phổ biến và hữu dụng như LLVM

    • Điều này làm tôi nhớ đến một câu từng đọc trong một tài liệu quản lý dự án không chính thức của NASA
      Đại ý là: “Nếu một sứ mệnh không tái sử dụng tên lửa hiện có, thì dự án đó sẽ trở thành dự án phát triển tên lửa, còn mọi thứ khác từng được coi là cốt lõi của sứ mệnh đều trở thành thứ yếu”
      Tôi còn nhớ thêm một ý nữa là có kèm theo tiền đề “thay vì thỏa hiệp để phù hợp với tên lửa hiện có, người ta có thể nghĩ rằng làm một tên lửa riêng cho sứ mệnh cụ thể sẽ rẻ hơn và hiệu quả hơn”
    • Điều này làm tôi nhớ đến cuộc phỏng vấn gần đây của Chris Lattner về thành công của Swift. Ông cho rằng một yếu tố thành công là có thể bắt đầu dùng xen kẽ Swift trong một dự án Objective-C lớn mà không cần viết lại gì cả
      Một phần thành công của Rust cũng nằm ở mức độ tương thích tương tự với C/C++
      Rất khó hình dung Zig có thể thành công nếu không có năng lực tương tự, nên tôi hy vọng họ sẽ không cứ thế thúc đẩy cột mốc này
    • Nó rất khác với LLVM. Ít nhất trong bối cảnh Apple tiếp quản dự án thì gần như không có nhiều lựa chọn
      Vì GCC không sẵn sàng cho phép hoặc triển khai những gì Apple muốn hay cần
    • Không phải là “đã được tuyên bố là mục tiêu”. Đây vẫn là một đề xuất chưa được chấp nhận
    • binutils gần giống một bộ công cụ đa năng để xử lý các định dạng mã nhị phân theo cách có tính di động, còn trình biên dịch thì không cần đến một nửa số đó, đặc biệt là phần di sản
      Nếu tập trung hơn như TCC, thì phần lớn công việc sẽ là ở phía sinh mã cho nhiều kiến trúc khác nhau
  • Ở đây có hai vấn đề. Một là sinh mã, hai là bootstrap
    Theo kinh nghiệm của tôi thì các optimization pass của trình biên dịch khá dễ viết và thú vị. Muốn hiểu register allocation và dạng SSA thì phải đọc bài báo, nhưng phần mã cho IR đi qua nhiều optimization pass rồi dần được gọt giũa thì khá vui để viết
    Có thể tạo ra các optimization pass chất lượng cao ngay cả khi không dùng LLVM. Nhưng giai đoạn tuyến tính hóa IR thành mã máy thì lại là công việc chán và tầm thường, trừ khi bạn thật sự thích mọi cách mà lệnh “mov [eax+8*ebx], 123” được mã hóa trên x86-32/64
    Nếu tối ưu kích thước nhị phân, liệu bạn có muốn đo xem trên nền tảng nào “push eax; push eax; push eax” ngắn hơn “add rsp,12” không? Đó mới chỉ là câu chuyện của x86, và nếu nhân lên với các kiến trúc không phải x86 — vốn lại chẳng quan trọng với đa số lập trình viên — thì còn lớn hơn nhiều
    Cũng rất có khả năng là những lỗi lớn trong code generator cho các kiến trúc ít dùng sẽ không bị phát hiện suốt nhiều năm
    Vấn đề thứ hai là bootstrap. Trình biên dịch Zig viết bằng Zig sẽ được biên dịch bằng gì? Chẳng hạn có thể dùng một trình biên dịch Zig tối thiểu, không tối ưu, viết bằng C để biên dịch trình biên dịch Zig
    Nhưng nếu nó không tối ưu thì sau đó lại phải dùng trình biên dịch Zig đã tối ưu để biên dịch lại chính trình biên dịch Zig. Không phải bài toán không giải được, nhưng một quy trình build dài và phức tạp có thể đẩy lùi những người muốn đóng góp

    • Bài này có vẻ nói về vấn đề bootstrap: https://ziglang.org/news/goodbye-cpp/
    • Zig đã bootstrap bằng backend C rồi nên vấn đề thứ hai không phải là vấn đề
  • Zig đã quảng bá rất nhiều việc nó có thể biên dịch C, thậm chí có thể cả C++, mà giờ lại muốn loại bỏ LLVM hoàn toàn thì trông khá cực đoan
    Trừ khi có nhiều người hơn hẳn tham gia hỗ trợ, còn không thì khả năng tiến gần mức hỗ trợ nền tảng của LLVM cũng có vẻ rất thấp
    Tôi có thể hiểu kế hoạch thêm backend riêng cho những ai muốn, nhưng bỏ hẳn LLVM thì có vẻ vội vàng

    • Nếu công việc đã bắt đầu rồi thì có thể là vội thật, nhưng cũng như những đề xuất khác không có nhãn “accepted” trong issue tracker, hiện tại đây mới chỉ là giai đoạn kêu gọi thảo luận và đề xuất phản biện
      Bây giờ là lúc đội ngũ thu thập phản hồi, tìm hiểu các use case bị ảnh hưởng và ước lượng tính khả thi, nên tôi thấy nó gần như là điều ngược lại với sự vội vàng
    • Nếu đọc phần thân của issue được liên kết thì không phải là loại bỏ hoàn toàn backend LLVM. Họ chỉ tách nó ra khỏi binary chính, và nếu hệ thống có cài LLVM thì vẫn có thể dễ dàng dùng nó làm backend
      Việc phải bundle một bản sao LLVM hơn 100MB dù không cần cho trường hợp phổ biến quả là hơi kỳ, nên như vậy cũng có lý. Nếu là lập trình viên thì nhiều người cũng đã cài sẵn rồi
      Tuy vậy, có thể sẽ khó đảm bảo Zig đã cài đặt hoạt động đúng với phiên bản LLVM của hệ thống. Cứ phải chờ xem
    • Nó vẫn xuất ra LLVM bitcode, chỉ là không còn phụ thuộc vào thư viện LLVM nữa
      https://github.com/ziglang/zig/issues/13265
    • Tôi cũng hiểu đúng y như vậy
      Gần đây tôi có đọc thêm về Zig, và còn thử dùng nó như một cách dễ dàng để biên dịch C++ với LLVM mà không phải vật lộn với package hệ thống. Việc có thể chuyển từ C/C++ sang Zig là một điểm bán hàng rất lớn
      Nó quá đột ngột và ngoài dự đoán. Tôi không biết điều đó đúng hay sai với dự án, nhưng từ góc nhìn của tôi thì nó thật sự rất bất ngờ
    • Tôi đang dùng Zig làm trình biên dịch C++ trong một dự án Rust. Đó là cách ít đau đớn nhất để cross-compile trên GitHub Actions
  • Một mặt, tôi tôn trọng sự kỹ lưỡng trong ý chí giảm phụ thuộc, nhưng cái giá phải trả có vẻ khá nghiêm trọng
    Mất khả năng tương thích C++ về cơ bản sẽ xóa đi lợi thế mà các fan Zig quanh tôi nhắc đến nhiều nhất
    Tổn thất hiệu năng, dù chỉ là tạm thời, cũng là một điểm cốt lõi khác mà họ thường nhắc cùng với điều đó

    • Có vẻ như phần lớn phản hồi đều phản đối đề xuất này
      Nói cho những ai chỉ đọc lướt thì đây không phải quyết định đã chốt, mà là đề xuất
  • Tôi đã viết toàn bộ các dự án và thư viện nhúng bằng Zig suốt khoảng 4 năm, giờ là nhiều kiến trúc được hỗ trợ tier 1 sẽ bị loại bỏ luôn sao?
    Ngôn ngữ là của họ nên họ có thể làm theo ý mình, nhưng nếu vậy thì tôi cũng muốn họ điều chỉnh lại branding cho phù hợp

    • Có thật là sẽ bị loại bỏ không?
      Có lẽ hỗ trợ tier 1 sẽ được chia thành hai nhóm: tier 1 tích hợp sẵn, và tier 1 thông qua backend LLVM tùy chọn
      Nếu một kiến trúc nào đó đã có hỗ trợ tier 1, thì tôi không thấy lý do gì việc biến backend LLVM thành phụ thuộc tùy chọn lại khiến hỗ trợ đó biến mất
      Như Andrew đã viết trong đề xuất, cách này thậm chí có thể mở ra con đường hỗ trợ tốt hơn cho các kiến trúc hiếm gặp hơn. Nếu có một backend Zig cho một kiến trúc bộ xử lý thú vị nào đó thì tôi sẵn sàng làm, nhưng tôi sẽ không bao giờ đóng góp cho LLVM. Làm việc với C++ không phải thứ tôi muốn làm như một thú vui
    • Ý là sẽ bỏ LLVM bằng cách tự triển khai lại mọi thứ mà LLVM đang làm theo cách riêng sao?
      Lợi ích của việc đó là gì? Chẳng phải là lãng phí nguồn lực sao?
    • Việc Zig còn chưa tới 1.0 đâu phải bí mật gì. Không thể đổ hoàn toàn trách nhiệm này lên họ, nhưng dù sao đây vẫn là một đề xuất khá cực đoan
    • Đây vẫn chỉ mới là giai đoạn đề xuất. GitHub issue đó chủ yếu cũng là nơi để đăng các use case ủng hộ hoặc phản đối, và nó chưa được chấp nhận
    • Vì đây vẫn chỉ là đề xuất, nên tôi nghĩ nếu đủ nhiều người lên tiếng — mà thực tế là đã có rất nhiều người làm vậy — thì đội ngũ nòng cốt cũng sẽ điều chỉnh cách tiếp cận
  • DLang có 3 trình biên dịch
    gdc dựa trên backend của bộ công cụ biên dịch Gnu, ldc dựa trên backend LLVM, còn dmd dựa trên bộ sinh mã x86 mà tôi đã viết cho Zortech/Symantec/Digital Mars
    Mỗi cái có ưu và nhược điểm riêng cũng như đối tượng sử dụng khác nhau, nhưng ngôn ngữ D mà chúng hỗ trợ thì giống nhau
    Nhìn chung người dùng thích có lựa chọn, và một số còn dùng song song từ hai cái trở lên

    • Có một khác biệt thú vị trong cách tiếp cận. D có vẻ như có các trình biên dịch hoàn toàn tách biệt, còn Zig thì dường như đang hướng tới việc để trình biên dịch Zig chính hỗ trợ LLVM như một backend nếu nó đã được cài đặt
      Nếu đúng là vậy thì tôi thích cách tiếp cận của Zig
    • Một ngôn ngữ khác cũng có nhiều trình biên dịch là Common Lisp. Có khoảng chục trình biên dịch sẵn sàng cho production, phần lớn miễn phí dù cũng có bản thương mại
      Điều đó rất hữu ích vì trong quá trình phát triển bạn có thể dùng trình biên dịch nhanh nhất, còn khi phát hành bản cuối thì có thể dùng trình biên dịch cho runtime nhanh nhất hoặc mức dùng bộ nhớ thấp nhất
      Ngoài ra, khi có một đặc tả ngôn ngữ mà mọi trình biên dịch đều tuân theo, ngôn ngữ sẽ có được sự ổn định và đảm bảo không bị hỏng đột ngột từ tầng bên dưới
      Dĩ nhiên, các ngôn ngữ như Zig — nơi bạn vẫn có thể thay đổi điều mình muốn để làm ngôn ngữ nhất quán, gọn gàng và mạnh mẽ hơn — cũng có điểm hay. Nhưng dạo gần đây tôi đánh giá cao kiểu ổn định kia hơn nhiều, vì nó cho phép tập trung tạo ra giá trị thực cho người dùng thay vì cứ phải chạy theo công cụ phát triển
    • Có lựa chọn cho người dùng nâng cao là một điểm cộng, nhưng việc phải lựa chọn tự nó đã là một nhược điểm lớn theo tôi
    • Tôi hiểu là người dùng thích có lựa chọn, nhưng nếu Zig muốn hướng tới mức độ chấp nhận rộng rãi về lâu dài thì tôi không nghĩ DLang là một tiền lệ tốt
  • Một trong những lý do chính khiến Zig hấp dẫn là nó có thể được cắm vào ngay như một lựa chọn thay thế cho trình biên dịch C/C++
    Bạn bè tôi nói rằng trên Windows, cài Zig làm trình biên dịch C/C++ dễ hơn bất kỳ lựa chọn thay thế nào khác
    Nếu đề xuất này được chấp nhận, cá nhân tôi nghĩ độ phổ biến của Zig sẽ tụt xuống mức của Hare hay các ngôn ngữ cực kỳ ngách khác
    Để khiến đồng nghiệp chịu thử Zig dù chỉ một lần, tôi còn phải gửi cho họ cả bài viết nói Uber dùng nó trong production. Nếu nó không có giá trị tức thì với các dự án hiện có, họ đã chẳng thèm nghĩ lần hai
    Dù vậy, tôi vẫn hiểu bối cảnh của đề xuất này. Thời gian biên dịch của LLVM có thể tệ đến mức khó chịu, và nếu có bytecode riêng thì cũng có thể triển khai những kỹ thuật tối ưu hóa rất hay. Xử lý bug của LLVM thì gần như là việc khó mà đụng vào được, và tôi cũng đã thấy điều đó trong hệ sinh thái Julia
    Nếu lời khuyên của tôi có giá trị gì đó, thì tôi nghĩ Zig nên 1) dùng bytecode tùy chỉnh cho bản build debug để có thời gian build nhanh và debug nhanh, và 2) dùng LLVM cho bản build release để có hiệu năng runtime cao
    Nếu vẫn có thể làm được phần 1) mà giữ nguyên hỗ trợ cross-compile C/C++, ví dụ chỉ chuyển riêng phần đó cho LLVM, thì dù phải đánh đổi bằng việc bảo trì thêm mã backend, đó có thể là phương án thỏa hiệp tốt nhất

    • Với tư cách là một trong những người xử lý bug LLVM trong hệ sinh thái Julia, thì đúng vậy
      Nó đòi hỏi một bộ kỹ năng riêng, khác với công việc ở trình biên dịch Julia cấp cao, và đôi khi cũng mất nhiều thời gian để các bản sửa lỗi được hợp nhất lên upstream
      Nhưng trên thực tế, chúng tôi có mối quan hệ khá tốt và hiệu quả với upstream, và nếu quyết định loại bỏ LLVM thì dự án hẳn đã làm được ít việc hơn rất nhiều
      Đặc biệt là hỗ trợ GPUhỗ trợ HPC, chẳng hạn như PPC, đều phụ thuộc vào LLVM
      Vì thế chúng tôi giữ quan điểm rằng Julia phải được build theo patchset/fork của mình, và chúng tôi không dành thời gian cho các bug phát sinh từ những bản build Julia không dùng các patch đó. Điều này đặc biệt hay xảy ra với các bản build từ distro
  • Nhìn từ góc độ đã theo dõi các nỗ lực làm backend không dùng LLVM ở những ngôn ngữ khác, thì đề xuất được liên kết toát ra sự ngạo mạn quá mạnh
    Nếu người viết không phải là chính người đó, tôi đã xem nó như một GitHub issue viết qua loa của một người mới với Zig
    Nó đánh giá thấp khối lượng công việc cần thiết, ngầm hạ thấp toàn bộ công sức đã đổ vào LLVM, và từng câu đều toát lên sự tự tin cùng vẻ macho kiểu “rõ ràng chúng ta có thể làm nó rẻ hơn, nhanh hơn, tốt hơn”. Thật đáng thất vọng
    Trước giờ tôi thực sự tôn trọng công việc của Andrew, nên tôi muốn thiện chí cho rằng có thể anh ấy viết vội hoặc viết ngẫu hứng nên không để ý là nó sẽ bị đọc theo cách đó
    Nhưng bài viết này không tạo cảm giác đáng tin, cũng không khiến tôi nhìn đề xuất đó với tâm thế cởi mở hơn

    • Tôi hoàn toàn không biết gì về backend LLVM, nhưng các thư viện cố giải quyết 100% vấn đề của người dùng thường rốt cuộc sẽ khó xử lý hơn và chậm hơn so với các phương án thay thế được tối ưu chuyên biệt hơn
      Webpack và esbuild là ví dụ như vậy
  • Thời điểm thích hợp để xây dựng thứ gì đó không dùng LLVM là vài năm trước. Nhưng ở thời điểm hiện tại, nếu bỏ tính năng C++ thì rất có thể đó sẽ là dấu chấm hết cho Zig
    Tôi ngạc nhiên là thay vì loại bỏ dần theo từng bước, họ lại không công bố kế hoạch viết trình biên dịch C++ riêng bằng Zig

    • Chỉ riêng việc viết parser cho C++ đã là một dự án khổng lồ
      Tôi cũng không chắc một cá nhân bắt đầu vào sinh nhật 18 tuổi của mình có thể viết được một trình biên dịch C++. Có khi quãng đời còn lại cũng chưa đủ để làm ra một trình biên dịch hoạt động được
  • Zig muốn trở thành C mới của thế giới, chứ không hẳn muốn trở thành C++ mới của thế giới
    Ngay trong đề xuất này cũng có thể thấy rằng biên dịch chéo cho C vẫn sẽ tiếp tục được hỗ trợ
    Đây có thể là một lựa chọn đúng. C hiện được dùng rất nhiều trong thế giới nhúng, và ở mảng đó LLVM không tốt
    Nếu là Zig, tôi sẽ muốn nhắm tới mọi vi điều khiển, và đây là con đường thực tế duy nhất để đạt được điều đó