ทำไมการเปรียบเทียบจึงมีราคาแพงใน GPU


10

ในขณะที่พยายามปรับปรุงประสิทธิภาพของคลาสการตรวจหาการชนกันของฉันฉันพบว่า ~ 80% ของเวลาที่ใช้ไปกับ gpu มันใช้กับเงื่อนไขอื่น ๆ ที่พยายามหาขอบเขตของถังที่มันควรวนผ่าน

อย่างแม่นยำมากขึ้น:

  1. แต่ละเธรดจะได้รับ ID โดย ID นั้นจะดึงสามเหลี่ยมจากหน่วยความจำ (3 จำนวนเต็มแต่ละรายการ) และโดย 3 นั้นจะดึงจุดยอดของมัน (3 ลอยแต่ละ)

  2. จากนั้นจะแปลงจุดยอดเป็นจุดกริดจำนวนเต็ม (ปัจจุบัน 8x8x8) และแปลงให้เป็นขอบเขตสามเหลี่ยมบนกริดนั้น

  3. ในการแปลง 3 คะแนนเป็นขอบเขตจะพบ min / max ของแต่ละมิติในแต่ละจุด

เนื่องจากภาษาการเขียนโปรแกรมที่ฉันใช้นั้นขาด minmax ที่แท้จริงฉันจึงสร้างมันขึ้นมาตัวเองมีลักษณะดังนี้:

procedure MinMax(a, b, c):
   local min, max

   if a > b:
      max = a
      min = b
   else:
      max = b
      min = a
   if c > max:
      max = c
   else:
      if c < min:
         min = c

   return (min, max)

ดังนั้นโดยเฉลี่ยแล้วมันควรจะเป็น 2.5 * 3 * 3 = 22.5 การเปรียบเทียบซึ่งจบลงด้วยการกินเวลามากกว่าการทดสอบจุดตัดสามเหลี่ยม - จริง (ประมาณ 100 * 11-50 คำแนะนำ)

ในความเป็นจริงฉันพบว่าการคำนวณล่วงหน้าถังที่จำเป็นใน cpu (เธรดเดียวไม่มี vectorization) ซ้อนในมุมมอง gpu พร้อมกับคำจำกัดความถังและทำให้ gpu ทำ ~ 4 อ่านพิเศษต่อเธรด 6 ครั้งเร็วกว่าพยายาม เพื่อหาขอบเขตในจุดที่ต้องการ (โปรดทราบว่าพวกเขาได้รับการคำนวณอีกครั้งก่อนการดำเนินการทุกครั้งเนื่องจากฉันจัดการกับตาข่ายแบบไดนามิก)

เหตุใดการเปรียบเทียบจึงช้าลงอย่างน่ากลัวสำหรับ GPU


2
คำถามของคุณเกี่ยวกับประสิทธิภาพระดับการเรียนการสอนของรหัสเฉพาะในฮาร์ดแวร์ประเภทใดประเภทหนึ่ง ฟังดูเหมือนคำถามการเขียนโปรแกรมมากกว่าคำถามวิทยาศาสตร์คอมพิวเตอร์สำหรับฉัน
David Richerby

7
ฉันเดาว่ามันไม่ใช่การเปรียบเทียบที่มีราคาแพง แต่เป็นกิ่งไม้ หากคอมไพเลอร์ไม่ได้ใช้ predication (หรือ GPU ไม่ได้จัดเตรียมไว้) สาขาจะถูกใช้ซึ่งทำให้เกิด "เธรด" การฟอร์ก (เนื่องจาก GPU เป็น SIMD-oriented) การแปลงสภาพเป็นมาสก์และการใช้มาสก์เพื่อสังเคราะห์การเคลื่อนไหว / สว็อปตามเงื่อนไขอาจเป็นทางเลือกที่สมเหตุสมผล
Paul A. Clayton

1
@ DavidRicherby ฉันไม่แน่ใจว่าเฉพาะเจาะจง คำถามนี้ใช้ไม่ได้กับสถาปัตยกรรม SIMD ใด ๆ หรือไม่
kasperd

1
@DavidRicherby: เหตุผลที่เราสอน comp arch ในแผนก CS นั้นเป็นเพราะ comp arch มีผลกระทบต่ออัลกอริทึมที่คุณเลือก สถาปัตยกรรม SIMD สามารถสร้างปริมาณงานสูงได้เฉพาะในกรณีที่คุณสามารถหาวิธีเขียนโปรแกรมโดยไม่มีกิ่งย่อยซ้อน
Wandering Logic

2
เนื่องจากคำตอบของ Wandering Logic ระบุไว้อย่างชัดเจนน้อยลง GPUs ทำงานโดยสมมติว่า "เธรด" จำนวนมากอยู่ในขั้นตอนเดียวกันพร้อมกัน ดังนั้น GPUs พูดอย่างคร่าว ๆ เอาทุกสาขามากกว่าแค่สาขาที่แท้จริง นี่คือเหตุผลที่ GPU ใช้ประโยชน์จากความจริงที่ว่าเพื่อนบ้านมักจะใช้กิ่งไม้เดียวกัน และประสิทธิภาพนั้นแย่มากเมื่อไม่เป็นเช่นนั้น
Rob

คำตอบ:


10

GPUs เป็นสถาปัตยกรรม SIMD ในสถาปัตยกรรม SIMD ทุกคำสั่งจะต้องมีการดำเนินการสำหรับทุกองค์ประกอบที่คุณดำเนินการ (มีข้อยกเว้นสำหรับกฎนี้ แต่ไม่ค่อยช่วย)

ดังนั้นในงานMinMaxประจำของคุณไม่เพียง แต่การโทรทุกครั้งจะต้องดึงคำสั่งสาขาทั้งสามคำสั่ง (แม้ว่าโดยเฉลี่ยจะได้รับการประเมินเพียง 2.5) แต่คำสั่งการมอบหมายทั้งหมดก็ใช้วัฏจักรเช่นกัน (แม้ว่าจะไม่ได้รับ )

ปัญหานี้บางครั้งเรียกว่าแตกต่างด้าย หากเครื่องของคุณมีช่องทางในการประมวลผล 32 SIMD เครื่องจะยังมีหน่วยดึงข้อมูลเดียว (นี่คือคำว่า "เธรด" โดยทั่วไปหมายถึง "เลนประมวลผล SIMD") ดังนั้นภายในเลนประมวลผลแต่ละ SIMD จะมีบิต "ฉันเปิดใช้งาน / ปิดการใช้งาน" และกิ่งก้านก็จัดการบิตนั้น (ข้อยกเว้นคือ ณ จุดที่ทุกเลน SIMD ถูกปิดใช้งานโดยทั่วไปหน่วยการดึงข้อมูลจะข้ามไปยังส่วน "อื่น" โดยตรง)

ดังนั้นในรหัสของคุณทุก ๆ ช่องทางในการดำเนินการของ SIMD:

compare (a > b)
assign (max = a if a>b)
assign (min = b if a>b)
assign (max = b if not(a>b))
assign (min = a if not(a>b))
compare (c > max)
assign (max = c if c>max)
compare (c < min if not(c>max))
assign (min = c if not(c>max) and c<min)

อาจเป็นได้ว่าในบาง GPUs การแปลงเงื่อนไขไปสู่การคาดการณ์นี้ช้าลงหาก GPU กำลังทำมันเอง ตามที่ระบุโดย @ PaulA.Clayton หากภาษาการเขียนโปรแกรมและสถาปัตยกรรมของคุณมีการดำเนินการย้ายแบบมีเงื่อนไขล่วงหน้า (โดยเฉพาะอย่างยิ่งหนึ่งในรูปแบบif (c) x = y else x = z) คุณอาจทำได้ดีกว่า (แต่อาจจะไม่ค่อยดีเท่าไหร่)

นอกจากนี้การวางc < minเงื่อนไขภายในelseของc > maxไม่จำเป็น แน่นอนว่ามันไม่ได้ช่วยให้คุณประหยัดอะไรเลยและ (เนื่องจาก GPU ต้องแปลงโดยอัตโนมัติเพื่อการคาดการณ์ล่วงหน้า) จริง ๆ แล้วมันอาจจะเจ็บที่จะซ้อนกันในสองเงื่อนไขที่แตกต่างกัน


2
(ขออภัยหากส่วนใดส่วนหนึ่งไม่ชัดเจนฉันพยายามหาคำตอบก่อนที่นักทฤษฎีจะปิดคำถามเป็นหัวข้อปิด)
Wandering Logic

สำหรับข้อมูลเพิ่มเติมเกี่ยวพื้นฐาน: http.developer.nvidia.com/GPUGems2/gpugems2_chapter34.htmlและสำหรับวิธีการแก้ปัญหามากขึ้นล่าสุด: eecis.udel.edu/~cavazos/cisc879/papers/a3-han.pdf
ฟอง

มันเป็นหัวข้อในแง่ที่ว่าอัลกอริธึมบางอย่างไม่สามารถเร่งผ่าน SIMD parallelism (เช่น: ทำงานช่วงเวลาและอื่น ๆ สำหรับการรักษาเชิงทฤษฎีว่าทำไม)
Rob

1
ต่อไปนี้เป็นการบรรยายเกี่ยวกับพื้นฐานของความแตกต่างของpeople.maths.ox.ac.uk/gilesm/cuda/lecs/lec3-2x2.pdfหมายเหตุจากสิ่งเหล่านี้ว่าปัญหา (ใน Nvidia อยู่แล้ว) เป็นเพียงการต่อวิปริต รหัสที่ใช้ในการแปรปรวนที่แตกต่างกันอย่างมีความสุขอาจแตกต่าง และกระดาษอื่นเสนอวิธีการหลีกเลี่ยงมันhal.inria.fr/file/index/docid/649650/filename/sbiswi.pdf
ฟอง

ในแนวทางที่แตกต่างกันเล็กน้อย แต่สอดคล้องกับความคิดเห็นที่ฉันเขียนภายใต้คำถามeprint.iacr.org/2012/137.pdfมีค่าการอ่าน: การชะลอตัว 10 เท่าเมื่อเทียบกับประสิทธิภาพที่คาดการณ์อาจเป็น "ปกติ" สำหรับ GPU เว้นแต่ว่าคุณจะหยุดทำงาน ในการประกอบ (โดยปกติจะมีเครื่องมือที่ไม่สนับสนุนอย่างเป็นทางการ) เป็นไปได้ว่าคอมไพเลอร์ที่มีการกำหนดเป้าหมาย GPU ทำได้ดีกว่า แต่ฉันจะไม่กลั้นหายใจ
Fizz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.