1 điểm bởi GN⁺ 3 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Từ Firefox 148, tối ưu hóa asm.js của SpiderMonkey đã bị tắt theo mặc định và phần mã liên quan sẽ bị loại bỏ trong các bản phát hành tới
  • asm.js là một tập con của JavaScript nên các trang hiện có vẫn tiếp tục hoạt động, nhưng sẽ chạy theo luồng JIT thông thường nên lợi ích tối ưu hóa sẽ biến mất
  • Nội dung asm.js có thể được biên dịch lại sang WebAssembly để có tốc độ thực thi nhanh hơn và tệp nhị phân nhỏ hơn
  • asm.js đã cho phép thực thi gần mức native bên trong nội dung web mà không cần sandbox riêng hay API thay thế để đối đầu với NaCl·PNaCl
  • OdinMonkey được đưa vào Firefox 22 năm 2013 đã giúp triển khai các dự án C/C++ như Unity và Unreal lên web, đồng thời trở thành nền tảng dẫn tới WebAssembly

Tắt tối ưu hóa asm.js

  • Từ Firefox 148, tối ưu hóa asm.js của SpiderMonkey đã bị tắt theo mặc định và toàn bộ mã liên quan sẽ bị loại bỏ trong các bản phát hành tương lai
  • Các trang sử dụng asm.js vẫn sẽ tiếp tục hoạt động
    • asm.js là một tập con của JavaScript thông thường, nên mã hiện có sẽ chạy theo luồng JIT thông thường như các script khác
    • Tuy vậy, lợi ích của các tối ưu hóa chuyên biệt cho asm.js sẽ không còn
  • Nếu bạn vẫn đang phân phối nội dung asm.js, khuyến nghị nên biên dịch lại sang WebAssembly
    • Biên dịch lại sang WebAssembly có thể mang lại tốc độ thực thi nhanh hơn và tệp nhị phân nhỏ hơn
    • Pipeline WebAssembly của SpiderMonkey đã phát triển vượt xa pipeline asm.js
  • Khi WebAssembly đã thành công và phần lớn việc sử dụng asm.js đã được chuyển đổi, chi phí duy trì đồng thời cả hai con đường trở nên quá lớn
    • Vẫn liên tục cần thời gian bảo trì
    • Để lại thêm bề mặt tấn công trong VM

Vai trò của asm.js và sự kết thúc của OdinMonkey

  • asm.js là câu trả lời của Mozilla cho câu hỏi mà NaCl và PNaCl đặt ra: “liệu có thể chạy mã với tốc độ native trên web hay không”
    • Cách tiếp cận là chọn một tập con JavaScript nghiêm ngặt, được định kiểu tĩnh, mà engine có thể nhận diện ngay lập tức rồi biên dịch thành mã native
    • Có thể ở lại bên trong nội dung web và dùng các Web API hiện có mà không cần sandbox riêng, IPC hay API thay thế
  • asm.js được đưa vào Firefox 22 năm 2013, cho phép các dự án như Unity và Unreal triển khai codebase C/C++ lên web chỉ bằng các công nghệ web tiêu chuẩn
  • Trình biên dịch asm.js có tên là OdinMonkey, và quá trình loại bỏ đang được theo dõi trong bug Ragnarök với tên “Twilight of OdinMonkey”
    • BaldrMonkey sinh ra từ OdinMonkey là trình biên dịch tối ưu hóa cho WebAssembly
    • RabaldrMonkey là trình biên dịch baseline cho WebAssembly
    • OdinMonkey đang bước vào giai đoạn kết thúc sau 13 năm hoàn thành vai trò của mình

1 bình luận

 
Ý kiến Hacker News
  • asm.js là câu trả lời của Mozilla cho câu hỏi mà NaCl và PNaCl đặt ra: “Làm sao chạy code với tốc độ native trên web?”
    Nếu là bây giờ thì có lẽ Chrome đã cứ thế thúc đẩy NaCl và PNaCl, rồi mọi người sẽ than phiền vì sao Safari và Firefox lại không theo kịp tiêu chuẩn “web”

    • Tôi vẫn cho rằng chúng ta đang ở sai dòng thời gian. PNaCl đã chết, và thay vì có một hậu duệ xứng đáng xuất hiện đúng lúc, chúng ta lại bị luộc sống trong món súp ứng dụng Electron.
      Có một thời gian tôi thật sự nghĩ rằng rồi chúng ta sẽ làm mọi thứ trong trình duyệt. Theo một nghĩa nào đó thì đúng là đang dần thành như vậy, nhưng cảm nhận tổng thể thì tệ hơn bao giờ hết. Tôi thích WASM và muốn tiếp tục thích nó, nhưng tốc độ trưởng thành của hệ sinh thái thì tệ đến mức khó tin.
      Tệ hơn nữa là giờ ta phải chạy các công cụ AI không đáng tin cùng đầu ra của chúng ngay trong chính các sandbox đó, trong khi các công ty lại đang bán sandbox được host và VM nền JS được host, tức là đi ngược hoàn toàn.
      Cuối cùng thì vấn đề dường như lúc nào cũng vậy. Không có tiền ở phía sandbox phía client.
    • Theo tôi nhớ thì không phải vậy. Khi đó đây là một thử nghiệm hữu ích, nhưng rốt cuộc đã không đi đến đâu.
      Về nội bộ thì nó hữu ích để sandbox Flash player, nhưng những giới hạn của cách tiếp cận dựa trên LLVM nhanh chóng trở nên rõ ràng với tất cả những người liên quan.
    • Thực ra lúc đó họ cũng về cơ bản đã cố làm như vậy. Họ định đưa nó qua các ủy ban tiêu chuẩn web và cũng đã đi đúng quy trình.
      Nếu tôi nhớ không nhầm thì lý do lớn khiến nó thất bại là NaCl là công nghệ quá “lớn”, còn asm.js lại quá “nhỏ”, nên dù asm.js khởi đầu muộn hơn vài năm, nó vẫn đạt mức sẵn sàng cho production trước.
    • Ý họ chắc là Chrome sẽ ép đi tiếp, còn Apple thì câu giờ bằng cách không nói gì trong khi không đầu tư cho đội WebKit, và những người cả tin trên Internet sẽ chiều theo phía Apple.
      Nhưng Apple có vẻ đã tăng đầu tư vào WebKit trong thập kỷ này sau khi áp lực quản lý bắt đầu nóng lên, nên nếu là ngày nay thì kết quả có thể đã khác.
    • Người ta than phiền khi có một tính năng hữu ích trên nền tảng web mà lại không có giải pháp thay thế tương thích cao. asm.js và sau đó là Wasm chính là những giải pháp thay thế như vậy.
      Vì thế khi đó ít bị than phiền hơn, còn bây giờ người ta phàn nàn về những thứ Safari không làm vì chúng bị xem là có hại cho App Store. May là EU giờ đang cố chỉnh Apple lại phần nào.
  • Buồn thì buồn nhưng cũng dễ hiểu. Một chi tiết thú vị là Figma ban đầu khởi đầu với codebase C++ hoàn chỉnh, và asm.js là yếu tố then chốt chứng minh rằng có thể chạy công cụ thiết kế trong trình duyệt.
    Họ chỉ chuyển sang WebAssembly sau khi đã có khách hàng trả tiền, và mức cải thiện thời gian tải cũng khá lớn. asm.js vẫn là JS nên bundle nặng hơn và code phải được parse thành AST, còn WASM thì không.

    • Tôi không hiểu có gì buồn đến thế. Nó chỉ là một đích biên dịch từng có ý nghĩa ở một thời điểm nào đó.
      Cũng giống như buồn vì i386-unknown-freebsd1 không còn được hỗ trợ nữa.
    • Điều đáng buồn là lẽ ra chúng ta có thể đã có một ứng dụng desktop Figma native gọn gàng.
  • Vậy là cái chết của asm.js cuối cùng đã đến sao? Chúng ta đang rời xa dòng thời gian của lời tiên tri.
    https://www.destroyallsoftware.com/talks/the-birth-and-death...
    Nếu bạn chưa xem thì cực kỳ khuyến nghị. Tùy định nghĩa “hay nhất”, đây có thể là bài thuyết trình công nghệ hay nhất từng có.

    • Cái chết của công nghệ này đã cắt đứt sợi chỉ tiên tri. Hoặc là tải lại save game để khôi phục tấm thảm định mệnh, hoặc cứ tiếp tục vật lộn trong thế giới đổ nát do chính mình tạo ra.
    • Tôi xem lại bài đó hai ba lần mỗi năm. Đây là ví dụ tuyệt vời về cách thuyết trình, cách đồng bộ slide deck với phần nói, và còn điểm qua cấu trúc vòng đặc quyền của hệ điều hành một cách bất ngờ là khá dễ hiểu.
      Một ngày nào đó, sau khi đi qua thời chiến và thoát khỏi sự ám ảnh tâm lý với các mô hình lập trình cũ kỹ, chúng ta có thể chuyển sang những cách tiến bộ hơn. Tất nhiên điều đó không có nghĩa ngân hàng của bạn sẽ ngừng chạy YavaScript trong ít nhất 85 năm tới.
    • Nếu thay asm.js bằng WASM thì lời đó vẫn đúng.
    • Không có gì phải lo. YavaScript sẽ sống mãi.
    • Nếu thay chiến tranh bằng COVID thì cả hai đều xảy ra vào năm 2020, nên cũng không lệch quá xa. Muốn biết có thật hay không thì vẫn phải đợi đến 2035.
  • Tôi sẽ không bao giờ quên lúc xem bài nói về JavaScript của Gary Bernhardt.[0] Đó là lần đầu tôi biết đến asm.js, và cũng là lúc rơi xuống hố thỏ của việc biên dịch code để chạy trong trình duyệt.
    Giờ đã 12 năm trôi qua, thật đáng ngạc nhiên khi bao nhiêu phần trong câu chuyện hư cấu của ông ấy đã trở thành hiện thực.
    [0] https://www.destroyallsoftware.com/talks/the-birth-and-death...

    • Phần về “ứng dụng dày (thick apps)” lúc nào cũng đọng lại với tôi. Một phần vì cái tên nghe buồn cười, một phần vì nó khá gần với hoàn cảnh của tôi.
      Lúc xem bài đó lần đầu tôi còn là thực tập sinh, và công ty đã tự làm toàn bộ compiler, IDE và debugger cho một hộp IO công nghiệp nhỏ. Compiler được viết bằng C, rồi chuyển sang JS bằng Emscripten, sau đó được “biên dịch” cùng phần IDE và debugger thành một file HTML khổng lồ, thực chất là nối lại với nhau. Việc upload code và debug diễn ra qua Ethernet, và mọi thứ được đẩy bằng Ajax.
      Nghe như một kiến trúc bị nguyền rủa, nhưng khách hàng lại thích. Vì nó không phải EXE nên không bị các bộ lọc IT doanh nghiệp quá tay của khách hàng chặn. Thế nên chúng tôi không chuyển sang Electron. Theo một nghĩa nào đó, nó đã có những yếu tố nguyên thủy của thick app.
    • Nếu không có sự trỗi dậy của AI thì WASM có lẽ đã trở thành đích biên dịch cấp máy cho mọi ngôn ngữ. Gary đã dự đoán được nhiều thứ, nhưng ông ấy không nhìn thấy AI.
  • Từ lâu tôi từng viết một chương nhỏ về asm.js trong một cuốn sách về WebGL.
    https://webglinsights.github.io/
    Chứng kiến sự trỗi dậy của asm.js, tiền thân của WebAssembly, là một điều thú vị. Trong những demo đầu tiên có những thứ thực sự ấn tượng, như Unreal Engine chạy trong trình duyệt. Nhìn nó lặn xuống ở đây thì hơi chua xót, nhưng nó đã mở đường cho những thứ tốt hơn rất nhiều.

  • Có lẽ chúng ta sẽ cần một transpiler từ asm.js sang WASM.
    Việc biên dịch code legacy bằng các phiên bản Emscripten cũ khá là bực bội. Đôi khi còn khổ chẳng kém việc phải cập nhật code JS để theo các thay đổi ABI tích lũy của Emscripten.

    • Binaryen trước đây từng có công cụ asm2wasm, nhưng theo tôi biết thì giờ đã bị loại bỏ. Tôi chưa tìm thấy công cụ tương đương nào khác.
      Ít nhất thì code asm.js vẫn sẽ chạy ngay cả khi tối ưu hóa asm.js bị tắt, nhưng có bộ chuyển đổi thì vẫn tốt hơn.
    • https://porffor.dev/
  • asm.js đã chết! WebAssembly muôn năm!

    • Nói công bằng thì tôi cứ tưởng asm.js đã bị đánh dấu ngừng dùng từ vài năm trước rồi, kể từ khi wasm xuất hiện.
  • Cá nhân tôi thấy quyết định này là một sai lầm. Dù vậy tôi không biết tác động thực tế sẽ lớn đến đâu. Theo tôi biết thì giờ cũng không còn nhiều người dùng asm.js.
    Nhưng wasm quá tách biệt khỏi JavaScript. Sau khi thử dùng ở mức hạn chế, tôi đã nghĩ hay là cứ biên dịch sang asm.js cho rồi.
    Tôi cũng không chắc Emscripten còn hỗ trợ đầy đủ hay không.
    Trên wasm, phần lớn web API đều không gọi được.
    Quan trọng hơn với công việc tôi định làm là từ JS không thể chuyển buffer zero-copy vào wasm.
    Mọi thứ đều là đánh đổi. Sự tách biệt là ưu điểm, nhưng cũng là nhược điểm.

    • Về khả năng tương tác với JS thì asm.js chắc chắn còn hạn chế hơn wasm. Về cơ bản nó bị giới hạn ở các giá trị số đơn giản và array buffer.
      Trong khi đó wasm ngày nay đã có GC types và còn có thể giữ các giá trị JS bằng externref.
      asm.js có lẽ cũng không làm được zero-copy buffer. Bên wasm có một proposal cho zero-copy buffer: https://github.com/WebAssembly/memory-control/blob/main/prop...
    • Nếu tôi nhớ không nhầm thì Emscripten đã bỏ hỗ trợ asm.js vào khoảng năm 2020, và đó có lẽ là toolchain quan trọng nhất từng hỗ trợ asm.js. Có thể sau đó là Rust, nhưng tôi không biết giờ còn hỗ trợ không.
      Ngay cả với asm.js nghiêm ngặt thì cũng không thể gọi trực tiếp phần lớn web API. Nó chỉ hỗ trợ số, không hỗ trợ chuỗi JS hay object, và quản lý heap C bên trong một đối tượng ArrayBuffer giống như WASM.
      Zero-copy buffer cũng vướng cùng vấn đề. Trong asm.js, bạn phải thoát ra “JavaScript thật” để gọi, và cũng không thể map trực tiếp một ArrayBuffer khác vào heap asm.js, nên cần copy. “JavaScript FFI” thực ra không khác nhiều giữa asm.js và WASM.
    • Nếu tôi không hiểu lầm thì asm.js cũng có cùng giới hạn đó đúng không? Tức là từ code asm.js không thể gọi trực tiếp web API, và vẫn cần xử lý riêng cho các hàm “bên ngoài”.
  • Tôi nhớ khi Mozilla công bố OdinMonkey, thứ được tối ưu hóa cực mạnh riêng cho code asm.js. Còn đội Chrome/V8 thì tập trung vào tối ưu JIT mang tính tổng quát hơn để chạy JavaScript nói chung nhanh hơn, đồng thời cũng có lợi cho asm.js.
    Chênh lệch tốc độ khi đó nghiêng về Firefox từ 2 đến 4 lần, và họ quảng bá điều đó khá mạnh :D
    Ngày nay hầu hết VM JavaScript của các trình duyệt đã hội tụ về thiết kế và tối ưu khá giống nhau, nên ngay cả không có Odin thì code asm.js vẫn sẽ chạy khá nhanh thôi.

  • Kế hoạch của tôi về việc tạo code JS lúc runtime để làm thuật toán chạy nhanh hơn coi như xong. Làm điều này bằng wasm có vẻ khó hơn nhiều.

    • Tạo code wasm ở runtime thực ra khá dễ. Có khi còn dễ hơn tạo code asm.js hợp lệ.
      Có một thư viện nhỏ xử lý khá nhiều việc như thế để phục vụ test: https://searchfox.org/firefox-main/source/js/src/jit-test/li...
    • Dùng thư viện thì không khó hơn đâu. Trong Rust, bạn có thể dùng cái này: https://crates.io/crates/wasm-encoder
      Còn trong JS thì có lẽ sẽ dùng https://www.npmjs.com/package/binaryen
    • Vẫn còn AssemblyScript. Nếu tôi không hiểu sai hoặc không nhầm về tính năng của nó thì có thể phù hợp với yêu cầu của bạn.
      https://www.assemblyscript.org/
    • Cứ thử dùng tập con asm.js xem hiệu năng ra sao. Tôi nhớ là ngay cả khi không có hỗ trợ asm.js đặc biệt trong trình duyệt, hiệu năng đầu ra của Emscripten vẫn tốt đến mức đáng ngạc nhiên.
    • Nó vẫn sẽ chạy thôi. Xét cho cùng asm.js vẫn chỉ là code JavaScript bình thường.
      Chỉ là nó sẽ không được parse hay thực thi nhanh như khi có pipeline chuyên biệt cho asm.js. Trừ khi là ứng dụng cực lớn, tôi nghĩ bạn sẽ khó nhận ra khác biệt lớn.