การเข้าถึงหน่วยความจำที่เหมาะสมที่สุดเมื่อใช้ตารางการค้นหาบน GPU?


9

ฉันกำลังสำรวจอัลกอริทึม isosurface บน GPU สำหรับโครงการปริญญาตรี ดังนั้นฉันจึงมีการใช้ซีพียูของ marching cubes ที่ดีและทำงานใน OpenFrameworks และตอนนี้อยู่ในขั้นตอนของการพยายามพอร์ตเข้ากับ GLSL compute shaders และพิจารณาข้อผิดพลาดก่อนที่ฉันจะดำดิ่งฉันเขียน Vert และ frag shaders ก่อนหน้านี้มันเป็นเรื่องใหม่สำหรับฉัน

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

ตาราง copypasta คลาสสิกของ Paul Bourke เป็นอาร์เรย์ 256 * 16 ดังนั้นหากใช้ชนิดไบต์สเกลาร์สิ่งนี้น่าจะถูกบรรจุลงในพื้นผิว 4kb หรือ SSBO

คำถามคือจะหยุดกระทู้ที่แตกต่างกันไม่ให้สะดุดกันได้อย่างไร คิวบ์จำนวนมากในแต่ละกลุ่มงานอาจมีการกำหนดค่าเดียวกันดังนั้นจึงพยายามเข้าถึงตำแหน่งเดียวกันในบัฟเฟอร์ในเวลาเดียวกัน มีวิธีแก้ปัญหาหรือการเพิ่มประสิทธิภาพเพื่อจัดการกับสิ่งนี้หรือไม่?


หากเป็นตารางค้นหาแบบอ่านอย่างเดียวคุณสามารถใช้บัฟเฟอร์ / พื้นผิวได้ คุณสามารถแพ็คให้เป็นหนึ่งในรูปแบบพื้นผิวปกติหรือคุณสามารถใช้คุณสมบัติใหม่ของ DX11 / OpenGL เพื่อให้มีรูปแบบที่กำหนดเอง UAV ในพื้นที่ DX11 หรือพื้นผิว / shader_image_load_store ในพื้นที่ OpenGL
RichieSams

นอกจากนี้ให้ดูงานนำเสนอนี้: cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdfสำหรับ CUDA แต่ควรให้ความคิดที่ดีขึ้นเกี่ยวกับสิ่งที่เกิดขึ้นบนฮาร์ดแวร์พื้นฐาน
RichieSams

ไม่ใช่คำตอบแบบเต็ม แต่มีหน่วยความจำน้อยกว่าที่คุณใช้ดีกว่าเนื่องจากมีแนวโน้มที่จะพอดีกับแคชและมีแคชน้อยกว่า หากคุณมีค่าที่สามารถแก้ไขได้เช่นคุณกำลังทำคะแนนในส่วนโค้งเป็นพื้นผิวคุณอาจลองใช้วิธีนี้เพื่อดูตารางการค้นหาเส้นโค้งคุณภาพสูงที่มีหน่วยความจำน้อยกว่า: blog.demofox.org/2016/02/22/
Alan Wolfe

คำตอบ:


6

สถานที่ที่ดีที่สุดในการวางตารางการค้นหาสำหรับตัวประมวลผล GPU ขึ้นอยู่กับขนาดของตารางการค้นหาและความถี่ / ความสอดคล้องของการเข้าถึง ในกรณีของคุณ (คุณกล่าวถึง 4kb) หน่วยความจำภายในที่ใช้ร่วมกันน่าจะดีที่สุด (สมมติว่าคุณไม่ต้องการหน่วยความจำนี้เพื่อวัตถุประสงค์อื่นในเคอร์เนลเดียวกัน) หน่วยความจำนี้มีชื่อแตกต่างกันใน API ที่แตกต่างกัน แต่เป็นสิ่งสถาปัตยกรรมเดียวกันและเป็นไปตามแนวทางการปฏิบัติงานที่เหมือนกัน:

  • CUDA: หน่วยความจำที่แชร์ของกลุ่ม
  • DirectCompute: หน่วยความจำแบบแบ่งใช้
  • OpenCL: หน่วยความจำท้องถิ่น
  • โลหะ: หน่วยความจำกลุ่ม
  • OpenGL: หน่วยความจำที่แชร์

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

โปรดทราบว่าฉันคิดว่านี่เป็นตารางการค้นหาแบบอ่านอย่างเดียว ตารางค้นหาแบบอ่าน - เขียนเป็นสัตว์ร้ายที่ต่างไปจากเดิมอย่างสิ้นเชิงและคุณไม่มีตัวเลือกที่ดีเลย


นอกจากนี้ยังมีกรณีที่บัฟเฟอร์แบบอ่านอย่างเดียวจะทำได้ดีกว่าการจัดเก็บข้อมูลแบบอ่านอย่างเดียว 4kb ในหน่วยความจำภายในที่ใช้ร่วมกัน ตัวอย่างเช่นการจัดเก็บไว้ในหน่วยความจำภายในอาจหมายถึงมีสำเนาที่ไม่ซ้ำกันของข้อมูลของคุณสำหรับทุกกลุ่มกระทู้ หากบัฟเฟอร์เหมาะสมกับแคชอาจเป็นไปได้ว่าแคชทำงานได้ดีกว่าหน่วยความจำภายในสำหรับรูปแบบการเข้าถึงแบบอ่านอย่างเดียว
John Calsbeek

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