การคอมไพล์ C และ C++ เป็น WebAssembly ด้วย Emscripten

ฟีเจอร์บนเว็บ: WebAssembly

ใช้ Emscripten เพื่อคอมไพล์ C และ C++ เป็นโมดูล WebAssembly (Wasm) ประสิทธิภาพสูงสำหรับเบราว์เซอร์

1. แฟล็กการคอมไพล์ Emscripten สมัยใหม่

เมื่อคอมไพล์และลิงก์กับ emcc หรือ em++ ให้ใช้แฟล็กโมดูลาร์สมัยใหม่เสมอ ดังนี้

  • -sEXPORT_ES6: แสดงไวยากรณ์โมดูล ES6 มาตรฐาน (import/export) แทนออบเจ็กต์ส่วนกลางเดิม การดำเนินการนี้จะตั้งค่า -sMODULARIZE โดยอัตโนมัติ
  • -sENVIRONMENT=web: ตัดโค้ดรันไทม์ Node.js/Shell เพื่อลดขนาดแพ็กเกจ
  • -sSTRICT: บังคับใช้ค่าเริ่มต้น Emscripten สมัยใหม่และไม่ทำงานเมื่อมีแฟล็กที่เลิกใช้งานแล้ว
  • -sALLOW_MEMORY_GROWTH: อนุญาตให้ฮีปหน่วยความจำเชิงเส้นของ WebAssembly ขยายแบบไดนามิกเมื่อจัดสรรหน่วยความจำ
  • -Oz (หรือ -O3) + -flto: เพิ่มประสิทธิภาพสำหรับขนาดเพย์โหลดขั้นต่ำในบิลด์ที่เผยแพร่

2. หลีกเลี่ยงการบล็อกเทรดหลัก

หากการเรียกใช้ WebAssembly มีแนวโน้มที่จะใช้เวลานาน (เช่น มากกว่า 2-3 มิลลิวินาที) ก็ไม่ควรเรียกใช้ในเทรดหลักของเบราว์เซอร์

วิธีหลีกเลี่ยงการเรียกใช้โค้ดดังกล่าวในเทรดหลักของเบราว์เซอร์มีหลายวิธี ดังนี้

  1. เรียกใช้โปรแกรม WebAssembly ทั้งหมดใน Web Worker วิธีนี้มักเป็นวิธีที่ง่ายที่สุดเนื่องจากไม่ต้องตั้งค่าการเข้าถึง SharedArrayBuffer หรือเปลี่ยนแหล่งที่มาของโปรแกรม

  2. ใช้ pthread หรือ Wasm Worker ซึ่งช่วยให้แชร์งานกับผู้ปฏิบัติงานจำนวนมากได้ แต่ต้องมีสิทธิ์เข้าถึง SharedArrayBuffer ซึ่งอาจเกี่ยวข้องกับการเพิ่มส่วนหัว HTTP ของ COOP/COEP

  3. เปลี่ยนโครงสร้างภายในโค้ด C/C++ เพื่อหลีกเลี่ยงการเรียกใช้ที่ใช้เวลานาน เช่น การแบ่งงานออกเป็นส่วนเล็กๆ ที่เรียกใช้ได้จาก requestIdleCallback

3. คอยสังเกตคำเตือนและข้อผิดพลาดเกี่ยวกับรันไทม์

ตรวจสอบว่าคุณได้ทดสอบโปรแกรม WebAssembly ที่ได้ และไม่มีคำเตือนหรือข้อผิดพลาดเกิดขึ้นในคอนโซล

สร้างและเรียกใช้โปรแกรมโดยเปิดใช้ -sASSERTIONS และแก้ไขข้อผิดพลาดรันไทม์ที่เกิดขึ้น

4. หลีกเลี่ยงการลิงก์แบบไดนามิก หากเป็นไปได้

Emscripten ทำงานได้ดีที่สุดกับไลบรารีแบบคงที่ (.a) ไลบรารีที่ใช้ร่วมกัน (.so, .dylib, .dll) มีประโยชน์น้อยกว่าในการติดตั้งใช้งานเบราว์เซอร์และอาจทำให้สิ่งต่างๆ ซับซ้อนโดยไม่จำเป็น

5. การพอร์ตไลบรารี C/C++ ที่มีอยู่

เมื่อผสานรวมไลบรารี C/C++ ที่มีอยู่กับระบบบิลด์มาตรฐาน ให้ทำดังนี้

โปรเจ็กต์ CMake

รวมคำสั่ง CMake ด้วย emcmake และ emmake:

mkdir build && cd build
emcmake cmake .. -DCMAKE_BUILD_TYPE=Release
emmake make

โปรเจ็กต์ Autoconf / Make

ใช้ emconfigure เพื่อตั้งค่าเป้าหมาย Toolchain การคอมไพล์แบบข้ามระบบ

emconfigure ./configure --host=wasm32-unknown-emscripten --disable-shared
emmake make