- นำเสนอแนวทางที่ใช้โครงสร้าง sparse strip เพื่อเพิ่มประสิทธิภาพในการทำ การเรนเดอร์กราฟิก 2D บน CPU
- งานวิจัยมุ่งเน้นโครงสร้างข้อมูลและวิธีประมวลผลเพื่อให้ทำ การเรนเดอร์ประสิทธิภาพสูง บน CPU แทน GPU
- ใช้ การแทนข้อมูลแบบ sparse เพื่อลดการใช้หน่วยความจำ และคงความเร็วในการเรนเดอร์ได้ดีแม้ในฉากที่ซับซ้อน
- ออกแบบมาเพื่อปรับปรุง ประสิทธิภาพการประมวลผลแบบขนาน และ การใช้แคช เมื่อเทียบกับวิธีเรนเดอร์บน CPU แบบเดิม
- เป็นงานวิจัยที่แสดงให้เห็นความเป็นไปได้ในการสร้างกราฟิก 2D คุณภาพสูงด้วย CPU เพียงอย่างเดียว
ภาพรวมงานวิจัย
- บทความนี้มีเป้าหมายที่ การเรนเดอร์กราฟิก 2D ประสิทธิภาพสูงบน CPU และสำรวจวิธีลดการพึ่งพา GPU
- แนวคิดหลักคือโครงสร้างข้อมูล sparse strip ซึ่งเก็บเฉพาะส่วนที่จำเป็นอย่างมีประสิทธิภาพ แทนการเก็บข้อมูลต่อเนื่องระดับพิกเซลทั้งหมด
- โครงสร้างนี้ช่วย ลดต้นทุนการเข้าถึงหน่วยความจำ และ เพิ่มความเร็วในการเรนเดอร์
โครงสร้าง sparse strip
- strip คือช่วงของพิกเซลที่ต่อเนื่องกันในภาพ 2D และจัดเก็บเฉพาะส่วนที่จำเป็นในรูปแบบ sparse
- วิธีนี้มีประสิทธิภาพเป็นพิเศษกับ ภาพที่มีพื้นที่ว่างจำนวนมากหรือเวกเตอร์กราฟิกที่ซับซ้อน
- เมื่อเทียบกับการเรนเดอร์แบบใช้บัฟเฟอร์ทั้งภาพ วิธีนี้ช่วย ลดการใช้หน่วยความจำ และ เพิ่มประสิทธิภาพของแคช
ประสิทธิภาพและการพัฒนา
- ใช้ คำสั่ง SIMD และ มัลติเธรด ของ CPU เพื่อดึงประสิทธิภาพการประมวลผลแบบขนานให้สูงสุด
- ผลการทดลองพบว่าสามารถประมวลผลฉากเดียวกันได้ในระดับ ประสิทธิภาพใกล้เคียงการเรนเดอร์แบบเรียลไทม์ แม้ไม่มี GPU
- การพัฒนาทำด้วย C++ และมีการทดสอบในหลายความละเอียดและหลายระดับความซับซ้อนของฉาก
ความเป็นไปได้ในการประยุกต์ใช้
- สามารถนำไปใช้ในสภาพแวดล้อมที่เน้น CPU เช่น การเรนเดอร์ UI, vector graphics engine, และ 2D pipeline ของ game engine
- ยังรองรับ การประมวลผลกราฟิก 2D ประสิทธิภาพสูง ได้ในระบบ embedded หรือสภาพแวดล้อมเซิร์ฟเวอร์ที่มีข้อจำกัดด้าน GPU
บทสรุป
- แนวทางแบบอิง sparse strip พิสูจน์ให้เห็นว่าสามารถ บรรเทาคอขวดของการเรนเดอร์บน CPU และ เพิ่มประสิทธิภาพการใช้หน่วยความจำ ได้
- ชี้ให้เห็นศักยภาพในฐานะ โมเดลทางเลือก สำหรับโครงสร้างการประมวลผลกราฟิกที่พึ่งพา GPU
- หากต้องการตัวเลขเพิ่มเติมหรือข้อมูลเปรียบเทียบโดยละเอียด ควรดูจากเนื้อหาใน PDF ต้นฉบับ
1 ความคิดเห็น
ความเห็นจาก Hacker News
โครงสร้าง
struct Stripที่นิยามไว้ในบทความดูเหมือนจะมีขนาด 64 บิต (8 ไบต์) แต่ในเนื้อหากลับระบุว่า 1 strip มีขนาด 64 ไบต์ลองคำนวณดูแล้วจริง ๆ น่าจะเป็นประมาณ 259×8 + 7296 ≈ 9KB ดูเหมือนว่าจะมีหน่วยอะไรสักอย่างผิดไป
อาจเป็นแค่การพิมพ์ผิดธรรมดา แต่ก็เป็นไปได้ว่าได้จัดสรรแต่ละ strip ตามหน่วยของ cache line (64 ไบต์)
ถ้าเป็นแบบนี้ก็จะช่วยเลี่ยง false sharing ได้ ดังนั้นเป็นไปได้ว่าตัวเรนเดอร์ตั้งใจทำแบบนั้น
ในบทความก็โฟกัสหลักไปที่การเปรียบเทียบเวลาในการรัน และไม่ได้พูดถึงการเปรียบเทียบพื้นที่จัดเก็บ
ลองดู Blaze: Parallel Rasterization on CPU ควบคู่กันไปด้วยก็น่าสนใจ
โปรเจกต์นี้น่าสนใจมาก ดูจากหัวข้อ 3.9 แล้วเอาต์พุตเป็น bitmap ดังนั้นสุดท้ายก็คงต้องคัดลอกภาพไปยัง GPU
ตอนนี้ Skia กำลังย้ายไปใช้ WebGPU และ WebGPU ก็รองรับ compute shader ด้วย ทำให้กราฟิก 2D ดูเหมือนจะกลายเป็นปัญหาที่แทบแก้ได้แล้วในแง่ของ portability และประสิทธิภาพ
แต่ก็ยังมีกรณีที่ CPU renderer มีประโยชน์อยู่ — เช่นในสภาพแวดล้อมเว็บที่ต้องคอมไพล์ shader ตอนรันไทม์เมื่อโหลดเพจ
ในทางทฤษฎีก็อาจทำโครงสร้างแบบเดียวกับ JS JIT ได้ คือเริ่มด้วย CPU renderer แล้วสลับไปใช้ GPU shader เมื่อพร้อม
ข้อดีอีกอย่างคือ ขนาดไบนารี เล็กกว่า WebGPU (ที่อิง dawn) นั้นค่อนข้างใหญ่
ลิงก์อ้างอิง
ในโปรเจกต์ที่ใหญ่กว่านี้ยังมีเวอร์ชันชื่อ Vello Hybrid ซึ่งให้ CPU จัดการงานเรขาคณิต และให้ GPU จัดการการลงสีพิกเซล
ไอเดียการใช้ CPU renderer ระหว่างรอ shader คอมไพล์ก็เคยพิจารณาอยู่ แต่ยังไม่ได้ลงมือทำ
กลับกัน ถ้าเรนเดอร์บน GPU ก็ต้องคัดลอกภาพกลับมาอีก ทำให้ไม่มีประสิทธิภาพ
ไม่นานมานี้ผมเขียนโค้ดสำหรับเรนเดอร์ วิถีโคจรแบบ N-body ความละเอียดสูง ที่มีจุดยอดหลายล้านจุด
เลยสงสัยว่าถ้านำรูปแบบ RLE ที่บทความนี้เสนอไปทำบน GPU มันจะยังทำงานได้ดีโดยคงความเรียบง่ายไว้หรือไม่
วิดีโอเดโม
น่าสนใจ อยากเห็นประสิทธิภาพแบบ single-core ของเรนเดอร์ที่เอามาเปรียบเทียบกัน
นั่นน่าจะบอกประสิทธิภาพของตัวโค้ดได้ดี เรนเดอร์ยอดนิยมบางตัวอาจช้ากว่าแต่ใช้ CPU น้อยกว่า
และยังดูผลได้จาก benchmark อย่างเป็นทางการของ Blend2D หรือ
vello_chart ที่ผมทำขึ้นโดยเพิ่มเรนเดอร์ตัวอื่นเข้าไปด้วย
หนึ่งในอาจารย์ที่ปรึกษาคือ Raph Levien คนเดียวกับผู้เขียนไลบรารี Libart ในอดีตหรือเปล่า?
อาจจะนอกประเด็นนิดหน่อย แต่สงสัยว่า ตัวพรีวิว PDF ของ GitHub เริ่มโหลดแค่บางหน้าตั้งแต่เมื่อไหร่
ผมรู้สึกว่าแบบเดิมที่โหลด PDF ทั้งไฟล์ทีเดียวแล้วให้เบราว์เซอร์เรนเดอร์น่าจะดีกว่า
สงสัยว่ามี benchmark สำหรับตรวจสอบ ความถูกต้อง (correctness) ของเรนเดอร์หรือไม่
คือวัด radiosity ของฉากจริงแล้วนำมาเทียบกับผลการจำลอง
ในงานเรนเดอร์แบบเรียลไทม์ บางครั้งก็ใช้งานเรนเดอร์ออฟไลน์อย่าง Arnold หรือ Octane เป็นตัวอ้างอิงในการเปรียบเทียบ
Cornell box บนวิกิ
ไม่มีเรนเดอร์ตัวไหนที่จำลองความเป็นจริงได้สมบูรณ์แบบ และทุกตัวก็ต้องยอมรับ trade-off บางอย่าง