คอมไพเลอร์ Vcc ทำลายอุปสรรคการเขียนโปรแกรม Shader แบบดั้งเดิม ด้วยการคอมไพล์ C++ ตรงไปยัง Vulkan

ทีมชุมชน BigGo
คอมไพเลอร์ Vcc ทำลายอุปสรรคการเขียนโปรแกรม Shader แบบดั้งเดิม ด้วยการคอมไพล์ C++ ตรงไปยัง Vulkan

โลกของการเขียนโปรแกรมกราฟิกส์ได้แบ่งออกเป็นสองแนวทางมาอย่างยาวนาน คือ ภาษา shader แบบดั้งเดิมอย่าง GLSL และ HLSL สำหรับงานกราฟิกส์ และภาษาที่มีความสามารถมากกว่าอย่าง C++ สำหรับการคำนวณทั่วไป การแบ่งแยกนี้สร้างปัญหาให้กับนักพัฒนาที่ต้องจัดการกับไวยากรณ์ที่แตกต่างกัน ฟีเจอร์ที่จำกัด และโค้ดเบสที่แยกจากกัน ตอนนี้ คอมไพเลอร์ Vcc สัญญาว่าจะเชื่อมช่องว่างนี้ด้วยการอนุญาตให้โค้ด C++ มาตรฐานทำงานโดยตรงเป็น Vulkan shader

ปัญหาของภาษา Shader แบบดั้งเดิม

ภาษา shader ปัจจุบันยังคงมีภาระจากยุคแรกเริ่มเมื่อฮาร์ดแวร์กราฟิกส์มีข้อจำกัดมากกว่านี้ GLSL และ HLSL ถูกออกแบบมาเมื่อโปรแกรม shader ยังเรียบง่ายและมีขนาดเล็ก ทำให้เกิดข้อจำกัดเรื่อง pointer การเรียกตัวเองซ้ำ และการจัดสรรหน่วยความจำแบบไดนามิก ข้อจำกัดเหล่านี้สมเหตุสมผลในอดีต แต่การเขียนโปรแกรมกราฟิกส์สมัยใหม่ต้องการโค้ดที่ซับซ้อนมากกว่านี้

ชุมชนนักพัฒนาเริ่มหงุดหงิดกับข้อจำกัดเหล่านี้ นักพัฒนามักพบว่าตัวเองต้องเขียนลอจิกซ้ำในหลายภาษา - ครั้งหนึ่งสำหรับโค้ด CPU และอีกครั้งสำหรับ GPU shader การทำซ้ำนี้สร้างบัก เสียเวลา และทำให้การดีบักยากลำบากเพราะอัลกอริทึมเดียวกันอาจทำงานแตกต่างกันในแต่ละแพลตฟอร์ม

ข้อจำกัดปัจจุบันของภาษา Shader:

  • ไม่รองรับ pointer ใน GLSL/HLSL แบบดั้งเดิม
  • การเรียกซ้ำ (Recursion) ถูกห้ามหรือมีข้อจำกัดอย่างมาก
  • ไม่มีการจัดสรรหน่วยความจำแบบไดนามิก
  • รองรับ function pointer อย่างจำกัด
  • มีเวิร์กโฟลว์การคอมไพล์และดีบักแยกต่างหาก

เหตุผลที่ C++ สำหรับ Shader สมเหตุสมผล

การผลักดันให้ใช้การเขียนโปรแกรม shader ที่ใช้ C++ ไม่ได้เป็นเพียงเรื่องความสะดวก CUDA ได้พิสูจน์แล้วว่า C++ สามารถทำงานได้อย่างยอดเยี่ยมสำหรับการเขียนโปรแกรม GPU โดยรองรับมาตรฐาน C++20 เต็มรูปแบบในขณะที่ยังคงประสิทธิภาพสูงสุด ข้อมูลเชิงลึกที่สำคัญคือการเรียนรู้ที่จะเขียน C++ ที่ทำงานร่วมกับฮาร์ดแวร์ GPU แทนที่จะต่อต้านมัน

นักพัฒนาหลายคนในชุมชนได้สัมผัสประโยชน์ด้วยตัวเอง ไลบรารี Mathematics ของ Unity แสดงให้เห็นแนวทางนี้อย่างสมบูรณ์แบบ - มันให้ไทป์ C# ที่สะท้อน vector และ matrix ในตัวของ HLSL อย่างแม่นยำ สิ่งนี้ช่วยให้นักพัฒนาเขียนฟังก์ชันคณิตศาสตร์ครั้งเดียวใน C# และคัดลอกไปยังไฟล์ HLSL โดยตรงโดยไม่ต้องเปลี่ยนแปลงใดๆ

ผมแค่คัดลอกและวางส่วนของโค้ด CPU ตรงไปในไฟล์ HLSL โดยคาดหวังเต็มที่ว่าจะเกิด syntax error หรือต้องปรับแต่ง แต่ไม่เลย มันทำงานได้อย่างสมบูรณ์แบบ ไม่ต้องเปลี่ยนแปลงอะไรเลย

ประสบการณ์การพัฒนาที่ดีกว่าขับเคลื่อนการยอมรับ

นอกเหนือจากการพิจารณาประสิทธิภาพแล้ว ประสบการณ์การพัฒนายังมีบทบาทสำคัญในแนวโน้มนี้ C++ มีเครื่องมือที่เหนือกว่าเมื่อเปรียบเทียบกับภาษา shader แบบดั้งเดิม - debugger ที่ดีกว่า เฟรมเวิร์กสำหรับทดสอบ การเน้นไวยากรณ์ และการสนับสนุน IDE เมื่อทำงานกับโปรเจกต์กราฟิกส์ที่ซับซ้อน เครื่องมือเหล่านี้สามารถเร่งการพัฒนาและลดบักได้อย่างมีนัยสำคัญ

ความสามารถในการดีบักลอจิก shader บน CPU ก่อน จากนั้นจึงย้ายไปยัง GPU ด้วยการเปลี่ยนแปลงเพียงเล็กน้อย แสดงถึงการปรับปรุงเวิร์กโฟลว์ที่สำคัญ เครื่องมือดีบัก CPU มีความเป็นผู้ใหญ่มากกว่าทางเลือกของ GPU ทำให้แนวทางนี้มีคุณค่าเป็นพิเศษสำหรับอัลกอริทึมที่ซับซ้อนอย่าง path tracing หรือการคำนวณแสงขั้นสูง

ความท้าทายทางเทคนิคและแนวทางแก้ไข

คอมไพเลอร์ Vcc เผชิญกับอุปสรรคทางเทคนิคที่สำคัญในการแปล C++ เป็นโค้ดที่เข้ากันได้กับ shader GPU สมัยใหม่รองรับฟีเจอร์อย่าง buffer device address สำหรับการดำเนินการแบบ pointer แต่ความสามารถเหล่านี้ไม่สามารถใช้ได้ทั่วไปในทุกแพลตฟอร์ม อุปกรณ์ Android มือถือโดยเฉพาะอาจอ้างว่ารองรับฟีเจอร์ Vulkan ขั้นสูงในขณะที่มีปัญหาไดรเวอร์ในทางปฏิบัติ

คอมไพเลอร์ยังต้องจัดการ control flow อย่างระมัดระวัง สถาปัตยกรรม GPU ทำงานได้ดีที่สุดกับ structured control flow แต่ความยืดหยุ่นของ C++ สามารถสร้างรูปแบบที่ไม่สามารถแมปไปยังโมเดลการทำงานของ GPU ได้ดี ฟีเจอร์อย่าง subgroup intrinsic ต้องการการจัดการพิเศษที่คอมไพเลอร์ C++ มาตรฐานไม่ได้ให้

สถานะการรองรับแพลตฟอร์ม:

  • Buffer device addresses: รองรับ 97.89% ใน Vulkan 1.2
  • Mobile Android: การรองรับของไดรเวอร์มีข้อจำกัด/ไม่เสถียร
  • Desktop GPUs: รองรับอย่างแพร่หลาย
  • Subgroup intrinsics: ต้องการ structured control flow ที่ยังไม่ได้ถูกพัฒนา

โมเมนตัมของอุตสาหกรรมกำลังสร้างขึ้น

อุตสาหกรรมกราฟิกส์กำลังเคลื่อนไปสู่โมเดลการเขียนโปรแกรมแบบรวม DirectX ของ Microsoft ตอนนี้รองรับ SPIR-V และภาษาใหม่อย่าง Slang (ซึ่งเป็น HLSL++ โดยพื้นฐาน) กำลังได้รับความนิยม แม้แต่ Metal Shading Language ของ Apple ก็ใช้ subset ของ C++ ในขณะเดียวกัน ภาษา shader แบบดั้งเดิมกำลังสูญเสียโมเมนตัม - Khronos ยอมรับว่าการพัฒนา GLSL หยุดชะงักโดยพื้นฐาน โดยบริษัทส่วนใหญ่เปลี่ยนไปใช้ HLSL หรือทางเลือกใหม่ๆ

การบรรจบกันนี้สมเหตุสมผลทั้งจากมุมมองทางเทคนิคและธุรกิจ เกมเอนจินและแอปพลิเคชันกราฟิกส์โดยทั่วไปเขียนด้วย C++ ดังนั้นการใช้ภาษาเดียวกันสำหรับ shader จึงขจัดการเปลี่ยนบริบทและลดเส้นโค้งการเรียนรู้สำหรับนักพัฒนา

คอมไพเลอร์ Vcc แสดงถึงก้าวสำคัญในการทำให้การเขียนโปรแกรม GPU เข้าถึงได้และมีประสิทธิผลมากขึ้น แม้ว่าจะยังมีความท้าทายเรื่องความเข้ากันได้ของแพลตฟอร์มและการเพิ่มประสิทธิภาพ แต่แนวทางพื้นฐานของการปฏิบัติต่อ shader เป็นภาษาเฉพาะโดเมนที่ฝังอยู่ใน C++ ดูเหมือนจะเป็นอนาคตของการเขียนโปรแกรมกราฟิกส์

อ้างอิง: No More Shading Languages: Compiling C++ to Vulkan Shaders