ลอยสองหรือทั้งสองอย่างสำหรับคลาส Vector 2 มิติ?


11

ขณะนี้ฉันกำลังเขียนเอนจิ้นเกม 2D ที่ใช้ OpenGL เป็นแพลตฟอร์มขนาดเล็กสำหรับสตูดิโอของเรา เมื่อฉันค้นคว้าคลาส Vector 2 มิติที่จะใช้ฉันสะดุดกับกระบวนทัศน์การออกแบบที่แตกต่างกันสามแบบ:

  • ลอยและโทรโดยค่าเหมือนในบทความ Gamasutra นี้ ดูเหมือนว่าจะเร็ว แต่มีความแม่นยำน้อย (ดูหัวข้อนี้ ) Pro: รวดเร็วพกพาและใช้งานได้กับห้องสมุดส่วนใหญ่

  • Double & Call-by-Reference หากฉันเข้าใจบทความข้างต้นถูกต้องฉันสามารถใช้ตัวแปรความแม่นยำสองคู่แทนตัวเลขทศนิยม 4 ตัว ตามด้ายข้างต้นสองครั้งยังคงช้ากว่าลอย

  • เทมเพลตสำหรับ double และ float: หนังสือยอดนิยม " Game Engine Architecture " ใช้เทมเพลตเพื่อให้สามารถใช้ float และ double ได้ตามต้องการ ข้อเสียที่ชัดเจนคือการขยายโค้ด นอกจากนี้ฉันสงสัยว่ารหัสสามารถปรับให้เหมาะสมโดยไม่ต้องเขียนสองชั้นโดยทั่วไป

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


ช้ากว่าที่ ? คุณไม่สามารถพูดเกี่ยวกับความเร็วได้หากไม่ได้เชื่อมโยงกับสถาปัตยกรรมเฉพาะ
o0 '

2
@ Lo'oris: ฉันไม่รู้สถาปัตยกรรมใดที่ double เร็วกว่า float

แทนที่จะเขียนคลาสเวกเตอร์ของคุณเองลองใช้ของ Sony ( bulletphysics.org/Bullet/phpBB3/ … ) มันเป็น "ไลบรา" เฉพาะส่วนหัวที่ดรอปอินอย่างง่ายซึ่งได้รับการเพิ่มประสิทธิภาพแบบไมโครและเวกเตอร์ไลบรารีทั้งหมดนั้นเป็นอินเทอร์เฟซภายนอกแบบเดียวกันอยู่แล้ว

@Joe: 2 คู่แทน 4 ลอย?
o0 '

@ Lo'oris: คำถามนี้เป็นคำแปลก ๆ ฉันไม่รู้ว่าผู้ถามสับสนหรือแค่คุณ - คุณใช้สองคู่ "แทนที่จะเป็น" สี่ลอยเมื่อจัดการกับ SIMD เพราะการลงทะเบียนกว้าง 128 บิต คุณยังต้องดำเนินการกับจำนวนที่เท่ากันและคุณทำด้วยความเร็วครึ่งเดียว

คำตอบ:


9

ฉันมักจะใช้โฟลทเว้นแต่ว่าฉันมีเหตุผลที่จะใช้สองเท่าเท่าที่ฉันจะใช้ int เว้นแต่ว่าฉันมีเหตุผลที่จะใช้ int64_t

โฟลทไม่มีปัญหาในการคำนวณเลขจำนวนเต็มที่แม่นยำจนถึง 2 24ซึ่งเป็นสิ่งที่คนส่วนใหญ่กลัว (ไร้เหตุผลส่วนใหญ่) การทวีคูณไม่ได้แก้ปัญหาค่าทั่วไปที่ไม่สามารถแสดงได้อย่างแน่ชัด - ไม่ว่าคุณจะได้รับ 0.10000001 หรือ 0.10000000000000001 คุณยังต้องแน่ใจว่ารหัสของคุณพิจารณาว่า "เท่ากับ" ถึง 0.09999999

การเล่นเกมจะช้าลงเป็นสองเท่าในทุกแพลตฟอร์มที่คุณสนใจเกี่ยวกับการเขียนเกมใช้แบนด์วิดท์หน่วยความจำสองเท่าและมีคำสั่ง CPU เฉพาะน้อยกว่า

โฟลตที่มีความแม่นยำเดียวยังคงเป็นมาตรฐานสำหรับอินเตอร์เฟสกราฟิกฮาร์ดแวร์ทั้งในด้าน C / C ++ และส่วนภายใน

คุณอาจต้องใช้เวกเตอร์คู่ในบางครั้ง แต่ควรใช้เมื่อจำเป็นไม่ใช่ค่าเริ่มต้น

สำหรับเทมเพลต - คุณถูกต้องเพื่อประสิทธิภาพสูงสุดคุณจะต้องเชี่ยวชาญเทมเพลตด้วยตนเองอยู่ดี นอกเหนือจากนั้นฉันทำการทดสอบบางอย่างสำหรับรหัสเทมเพลตในช่วงสุดสัปดาห์ (ทำ IntRect และ FloatRect 4-ple) และพบว่าเวอร์ชันเทมเพลตใช้เวลาในการคอมไพล์อีกประมาณ 20x นานกว่าการทำซ้ำรหัสซึ่งมีประมาณ 15 บรรทัด . การทำซ้ำซ้ำซาก แต่การรอคอยการคอมไพล์ดูดมากขึ้น - และมันก็ไม่เหมือนว่าฉันจะต้องใช้ StringRect หรือ FooRect


" คู่ช้ากว่าทุกแพลตฟอร์ม [... ] " -
สุดยอด

3

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

ผมพบว่ามันค่อนข้างน่าสนใจที่จะอ่านคำตอบในคำถามนี้กองมากเกินไปนี้: "ลอยเทียบกับผลการดำเนินงานคู่" นอกจากนี้ยังมีเธรด gamedev.netพร้อมการอภิปรายเรื่องประสิทธิภาพสองเท่าใน GPU ฉันคิดว่ามันปลอดภัยที่จะสมมติว่าคู่ช้ากว่าลอยอย่างน้อยใน GPU หลายตัวและฉันมักจะใช้ฟังก์ชั่น OpenGL ลอยเหนือคู่ของพวกเขา สิ่งนี้อาจใช้ไม่ได้ในทุกวันนี้ แต่ถ้าคุณคิดว่าไม่ใช่ทุกคนที่รันเกมของคุณมี GPU รุ่นล่าสุดที่มีการสนับสนุนสองเท่าฉันคิดว่านี่เป็นเหตุผลที่เพียงพอที่จะใช้โฟลตและเพิ่มประสิทธิภาพเล็กน้อย


1
จากคำถาม SO: "ในโปรเซสเซอร์ x86 อย่างน้อยที่สุดโฟลว์และดับเบิ้ลจะถูกแปลงเป็น FPU จริง 10 ไบต์สำหรับการประมวลผล" แม้ว่าจะเป็นความจริง แต่ก็ละเลยทั้งคำสั่ง SIMD และข้อกำหนดเพิ่มเติมของหน่วยความจำ (= การเชื่อมโยงแคชที่แย่ลงแบนด์วิธหน่วยความจำเพิ่มเติม) ของคู่ซึ่งทั้งสองอย่างต่อเนื่องทำให้ช้ากว่าลอยในการทดสอบในโลกแห่งความเป็นจริง

ฉันคิดว่ามีการจับ คุณควรแสดงความคิดเห็นว่าในคำตอบ SO ฉันจะถอนมันออกไป
Ricket

มีความคิดเห็นอยู่แล้ว

1
เมื่อคุณนำ XNA ขึ้นมาฉันอาจชี้ให้เห็นว่า Direct2D นั้นใช้การลอยตัวที่มีความแม่นยำเดียวเช่นกัน
Mike Strobel

และเพื่อความสมบูรณ์ OpenGL มีวิธีลอยตัวและรุ่นสองเท่าดังนั้นจึงเป็นกลางในแง่นี้
Ricket
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.