กาลครั้งหนึ่งเมื่อ> เร็วกว่า <…เดี๋ยวก่อนอะไรนะ?


280

ฉันกำลังอ่านบทแนะนำ OpenGL ที่ยอดเยี่ยม มันยอดเยี่ยมมากเชื่อใจฉัน หัวข้อที่ฉันอยู่ในขณะนี้คือ Z-buffer นอกเหนือจากการอธิบายว่ามันคืออะไรผู้เขียนกล่าวว่าเราสามารถทำการทดสอบเชิงลึกที่กำหนดเองเช่น GL_LESS, GL_ALWAYS และอื่น ๆ นอกจากนี้เขายังอธิบายว่าความหมายที่แท้จริงของค่าความลึก ที่กำหนดเอง ฉันเข้าใจจนถึง แล้วผู้เขียนก็บอกว่ามีอะไรที่ไม่น่าเชื่อ:

ช่วง zNear สามารถมากกว่าช่วง zFar; ถ้าเป็นเช่นนั้นค่าพื้นที่หน้าต่างจะถูกย้อนกลับในแง่ของสิ่งที่ถือว่าใกล้เคียงที่สุดหรือไกลที่สุดจากผู้ชม

ก่อนหน้านี้ได้มีการกล่าวว่าค่า Z- ช่องว่างของหน้าต่างอยู่ใกล้ที่สุดและ 1 มากที่สุด อย่างไรก็ตามหากค่าคลิปพื้นที่ Z ของเราถูกลบความลึก 1 จะอยู่ใกล้กับมุมมองมากที่สุดและความลึกของ 0 จะใกล้เคียงที่สุด แต่ถ้าเราพลิกทิศทางของการทดสอบความลึก (GL_LESS ถึง GL_GREATER ฯลฯ ) เราจะได้ผลลัพธ์เดียวกัน มันเป็นเพียงแค่การประชุมเท่านั้น อันที่จริงการพลิกเครื่องหมายของ Z และการทดสอบเชิงลึกนั้นครั้งหนึ่งเคยเป็นการเพิ่มประสิทธิภาพที่สำคัญสำหรับเกมจำนวนมาก

ถ้าฉันเข้าใจอย่างถูกต้องฉลาดหลักแหลมการพลิกเครื่องหมายของ Z และการทดสอบเชิงลึกคืออะไร แต่การเปลี่ยนการ<เปรียบเทียบกับการ>เปรียบเทียบ ดังนั้นหากฉันเข้าใจอย่างถูกต้องและผู้แต่งไม่ได้โกหกหรือทำสิ่งต่าง ๆ ขึ้นมาการเปลี่ยนแปลง<ที่>เคยเป็นสิ่งสำคัญที่สุดสำหรับหลาย ๆ เกม

เป็นผู้เขียนทำสิ่งที่ขึ้นผมกำลังเข้าใจผิดอะไรหรือเป็นจริงกรณีที่ครั้งหนึ่งเคย<เป็นช้า ( จำเป็นขณะที่ผู้เขียนกล่าวว่า) มากกว่า>?

ขอบคุณสำหรับการชี้แจงเรื่องนี้ค่อนข้างอยากรู้อยากเห็น!

ข้อจำกัดความรับผิดชอบ: ฉันตระหนักดีว่าความซับซ้อนของอัลกอริทึมเป็นแหล่งข้อมูลหลักสำหรับการปรับให้เหมาะสม ยิ่งกว่านั้นฉันสงสัยว่าทุกวันนี้มันจะไม่สร้างความแตกต่างอย่างแน่นอนและฉันก็ไม่ได้ขอให้ทำสิ่งใดให้เกิดประโยชน์สูงสุด ฉันแค่เจ็บปวดอย่างมากอาจจะสงสัย


6
ดูเหมือนว่าลิงก์ไปยังบทช่วยสอนนี้จะหายไป (เมื่อเร็ว ๆ นี้) :(
TZHX

@TZHX: เนื่องจากคำตอบที่ได้รับการยอมรับถูกแต่งขึ้นโดยผู้เขียนบทช่วยสอนเราจึงหวังว่าจะได้พบมันอีกครั้ง ดูความคิดเห็นล่าสุดของฉันไปที่คำตอบของเขา :)
อาร์เมน Tsirunyan

3
อ้างอิง OpenGL กวดวิชาสามารถใช้ได้ที่นี่
Fons

(a <b) นั้นเหมือนกันกับ (b> a) ดังนั้นจึงไม่มีความจำเป็นที่จะต้องใช้การเปรียบเทียบทั้งสองในฮาร์ดแวร์ ความแตกต่างในประสิทธิภาพเป็นผลมาจากสิ่งที่เกิดขึ้นเป็นผลมาจากการดำเนินการเปรียบเทียบ นี่เป็นถนนที่ยาวและคดเคี้ยวเพื่อใช้อธิบายผลข้างเคียงทั้งหมด แต่นี่เป็นเพียงไม่กี่ตัวชี้ เกมที่ใช้เติมบัฟเฟอร์ความลึกเพื่อหลีกเลี่ยงการประมวลผลชิ้นส่วนที่มีราคาแพงกว่าสำหรับชิ้นส่วนที่ล้มเหลวในการทดสอบเชิงลึก Quake ใช้ในการแบ่งช่วงความลึกออกเป็นสองส่วนเพื่อหลีกเลี่ยงการล้างเฟรมบัฟเฟอร์เพราะเกมจะเต็มทุกพิกเซลบนหน้าจอและต่อไป
t0rakka

2
@Fons ดูเหมือนว่าลิงค์จะตายอีกครั้ง :(
nalzok

คำตอบ:


350

ถ้าฉันเข้าใจอย่างถูกต้องฉลาดหลักแหลมการพลิกเครื่องหมายของ Z และการทดสอบเชิงลึกนั้นไม่มีอะไรนอกจากการเปลี่ยนการเปรียบเทียบ <การเปรียบเทียบเป็นการ> ดังนั้นหากฉันเข้าใจอย่างถูกต้องและผู้แต่งไม่ได้โกหกหรือทำสิ่งต่าง ๆ ดังนั้นการเปลี่ยน <เป็น> เคยเป็นวิธีการเพิ่มประสิทธิภาพที่สำคัญสำหรับหลาย ๆ เกม

ฉันไม่ได้อธิบายอย่างนั้นโดยเฉพาะอย่างยิ่งเพราะมันไม่สำคัญ ฉันเพิ่งรู้สึกว่าเป็นเรื่องเล็กน้อยที่น่าสนใจที่จะเพิ่ม ฉันไม่ได้ตั้งใจจะทำตามขั้นตอนวิธีเฉพาะ

อย่างไรก็ตามบริบทเป็นกุญแจสำคัญ ฉันไม่เคยพูดว่า <การเปรียบเทียบนั้นเร็วกว่าการเปรียบเทียบ> ข้อควรจำ: เรากำลังพูดถึงการทดสอบความลึกของฮาร์ดแวร์กราฟิกไม่ใช่ซีพียูของคุณ operator<ไม่

สิ่งที่ฉันหมายถึงคือการเพิ่มประสิทธิภาพแบบเก่าโดยเฉพาะซึ่งคุณจะใช้หนึ่งเฟรม GL_LESSในช่วง [0, 0.5] เฟรมถัดไปคุณแสดงผลด้วยGL_GREATERช่วง [1.0, 0.5] คุณกลับไปกลับมาอย่างแท้จริง "พลิกเครื่องหมายของ Z และการทดสอบเชิงลึก" ทุกเฟรม

สิ่งนี้สูญเสียความแม่นยำในเชิงลึกไปหนึ่งบิต แต่คุณไม่จำเป็นต้องล้างบัฟเฟอร์ความลึกซึ่งกาลครั้งหนึ่งเป็นการทำงานที่ค่อนข้างช้า เนื่องจากการล้างเชิงลึกไม่เพียง แต่เป็นอิสระในวันนี้ แต่จริง ๆ แล้วเร็วกว่าเทคนิคนี้ผู้คนจึงไม่ทำอีกต่อไป


1
เหตุผลที่การล้างบัฟเฟอร์ความลึกเร็วขึ้นวันนี้มีสองประการด้วยกันทั้งสองประการขึ้นอยู่กับข้อเท็จจริงที่ว่า GPU ใช้บัฟเฟอร์ความลึกแบบลำดับชั้น ดังนั้นเพียงแค่ตั้งค่าสถานะของกระเบื้องให้ชัดเจน (ซึ่งเร็วมาก) การเปลี่ยนเครื่องหมายเปรียบเทียบความลึกอย่างไรก็ตามหมายความว่าบัฟเฟอร์ HiZ ทั้งหมดต้องถูกล้างข้อมูลเนื่องจากจะเก็บเฉพาะค่านาทีหรือค่าสูงสุดขึ้นอยู่กับเครื่องหมายเปรียบเทียบ
Jasper Bekkers

3
@NicolBolas: ความคิดเห็นของ PerTZHX ลิงก์ไปยังบทช่วยสอนของคุณในคำถามของฉันก็ตายไปแล้ว คุณช่วยบอกให้พวกเราทุกคนรู้ได้ไหมว่าบทช่วยสอนเคลื่อนไปที่ไหนและเลือกที่จะแก้ไขคำถามได้ไหม?
Armen Tsirunyan

2
บทเรียนมีอยู่ในเว็บเก็บถาวร หาก @NicolBolas อนุญาตมันจะเป็นประโยชน์สำหรับชุมชนถ้าเราสามารถย้ายพวกเขาไปยังตำแหน่งที่เข้าถึงได้มากขึ้น บางที GitHub หรืออะไรบางอย่าง web.archive.org/web/20150215073105/http://arcsynthesis.org/…
ApoorvaJ

3

คำตอบนั้นเกือบจะแน่นอนว่าไม่ว่าจะมีการใช้งานชิปตัวขับ + ตัวไหนก็ตาม Hierarchical Z ทำงานในทิศทางเดียวเท่านั้น - นี่เป็นปัญหาที่พบได้บ่อยในสมัยนั้น แอสเซมบลีระดับต่ำ / การแบรนช์ไม่มีส่วนเกี่ยวข้อง - Z-buffering ทำในฮาร์ดแวร์ฟังก์ชันที่คงที่และไพพ์ไลน์ - ไม่มีการเก็งกำไรและด้วยเหตุนี้จึงไม่มีการพยากรณ์สาขา


0

การเพิ่มประสิทธิภาพเช่นนั้นจะส่งผลเสียต่อประสิทธิภาพการทำงานของโซลูชั่นกราฟิกฝังตัวหลายตัวเพราะจะทำให้ framebuffer แก้ปัญหาได้อย่างมีประสิทธิภาพน้อยลง การล้างบัฟเฟอร์เป็นสัญญาณที่ชัดเจนไปยังไดรเวอร์ซึ่งไม่จำเป็นต้องจัดเก็บและกู้คืนบัฟเฟอร์เมื่อทำการ binning

ข้อมูลพื้นหลังเล็กน้อย: rasterizer แบบเรียงต่อกัน / การเรียงกระเบื้องประมวลผลหน้าจอในจำนวนของกระเบื้องขนาดเล็กมากซึ่งพอดีกับหน่วยความจำบนชิป สิ่งนี้จะลดการเขียนและอ่านไปยังหน่วยความจำภายนอกซึ่งจะลดทราฟฟิกของบัสหน่วยความจำ เมื่อเฟรมเสร็จสมบูรณ์ (สลับถูกเรียกหรือ FIFO ถูกลบทิ้งเนื่องจากเฟรมเต็มการเชื่อมโยง framebuffer จะเปลี่ยน ฯลฯ ) เฟรมเฟรมจะต้องได้รับการแก้ไข นี่หมายความว่าทุก bin ถูกประมวลผลตามลำดับ

คนขับรถจะต้องถือว่าเนื้อหาก่อนหน้านี้ต้องได้รับการเก็บรักษาไว้ การเก็บรักษาหมายความว่าต้องมีการเขียนถังขยะออกไปยังหน่วยความจำภายนอกและเรียกคืนภายหลังจากหน่วยความจำภายนอกเมื่อมีการประมวลผลถังอีกครั้ง การดำเนินการที่ชัดเจนบอกคนขับว่าเนื้อหาของถังขยะมีการกำหนดไว้อย่างดี: สีที่ชัดเจน นี่คือสถานการณ์ที่เล็กน้อยเพื่อเพิ่มประสิทธิภาพ นอกจากนี้ยังมีส่วนขยายเพื่อ "ทิ้ง" เนื้อหาบัฟเฟอร์


-8

มันเกี่ยวข้องกับการตั้งค่าสถานะบิตในการชุมนุมปรับสูง

x86 มีทั้งคำแนะนำ jl และ jg แต่โปรเซสเซอร์ RISC ส่วนใหญ่มีเพียง jl และ jz (ไม่ใช่ jg)


2
หากนั่นคือคำตอบก็จะทำให้เกิดคำถามใหม่ "สาขาที่ใช้" ช้ากว่า "สาขาที่ข้าม" ในโปรเซสเซอร์ RISC รุ่นแรกหรือไม่ แน่นอนว่าตอนนี้มันไม่ได้เป็นอย่างนั้นเท่าที่ฉันรู้ คุณควรจะเขียนforลูปที่มีสาขาแบบไม่มีเงื่อนไขไปข้างหลังและแบบมีเงื่อนไขหรือไม่และมักจะนำสาขาไปข้างหน้าเพื่อออกจากลูปแล้ว? ฟังดูน่าอึดอัดใจ
Pascal Cuoq

54
-1: คำถามนี้มีอะไรจะทำอย่างไรกับซีพียู GL_LESS และ GL_GREATER เป็นการดำเนินการเปรียบเทียบเชิงลึกซึ่งทำงานบน GPU
Nicol Bolas

8
ตลกเท่าไหร่ตัวแทนคุณจะได้รับคำตอบที่ถูกต้องกับชื่อ แต่มีน้อยมากที่จะทำกับคำถามจริง
Joshua

7
+1 ไม่คำตอบนี้ถูกต้องกับคำถามอย่างน้อยส่วนหนึ่ง คำถามคือ: "ผู้เขียนทำสิ่งต่าง ๆ ขึ้นมาหรือไม่ฉันเข้าใจผิดบางอย่างหรือเป็นกรณีที่เมื่อ <ช้ากว่า (เหมือนเดิมอย่างที่ผู้เขียนพูด) มากกว่า>?" มีสามตัวเลือกให้ คำตอบนี้เป็นการตอบสนองต่อความเป็นไปได้ของตัวเลือก 3 ไม่มีที่ไหนในบทความที่เป็นเทคโนโลยีของ CPU / GPU ที่กำหนดและไม่ต้องเป็น GPU (เกม 3 มิติแรกที่ใช้ CPU) ตกลง ... ฉันไม่คิดว่าจะมีเกม 3 มิติมากมายใน RISC :-)
xanatos

3
(และเพิ่มแท็ก GPU ที่ 20:34 การแก้ไขครั้งแรกมีเพียงแท็ก CPU การตอบสนองนี้เขียนเมื่อ 18:44)
xanatos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.