GPU ของฉันกำลังรออะไรอยู่


11

ฉันกำลังเขียนโปรแกรม OpenCL เพื่อใช้กับ GPU AMD Radeon HD 7800 series ของฉัน ตามคู่มือการเขียนโปรแกรม OpenCLของ AMD รุ่น GPU นี้มีคิวฮาร์ดแวร์สองคิวที่สามารถทำงานแบบอะซิงโครนัสได้

5.5.6 คิวคำสั่ง

สำหรับหมู่เกาะเซาท์เทิร์นและหลังจากนั้นอุปกรณ์ต่าง ๆ สนับสนุนฮาร์ดแวร์คำนวณคิวอย่างน้อยสองรายการ ที่ช่วยให้แอปพลิเคชันเพิ่มปริมาณงานของการแจกจ่ายเล็กน้อยด้วยคิวคำสั่งสองรายการสำหรับการส่งแบบอะซิงโครนัสและการดำเนินการที่เป็นไปได้ คิวการคำนวณฮาร์ดแวร์ถูกเลือกตามลำดับต่อไปนี้: first queue = แม้กระทั่งคำสั่ง OCL, คิวที่สอง = คิว OCL แปลก ๆ

ในการทำเช่นนี้ฉันได้สร้างคิวคำสั่ง OpenCL สองชุดแยกกันเพื่อป้อนข้อมูลไปยัง GPU โดยประมาณโปรแกรมที่ทำงานบนโฮสต์เธรดจะมีลักษณะดังนี้:

static const int kNumQueues = 2;
cl_command_queue default_queue;
cl_command_queue work_queue[kNumQueues];

static const int N = 256;
cl_mem gl_buffers[N];
cl_event finish_events[N];

clEnqueueAcquireGLObjects(default_queue, gl_buffers, N);

int queue_idx = 0;
for (int i = 0; i < N; ++i) {
  cl_command_queue queue = work_queue[queue_idx];

  cl_mem src = clCreateBuffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, ...);

  // Enqueue a few kernels
  cl_mem tmp1 = clCreateBuffer(CL_READ_WRITE);
  clEnqueueNDRangeKernel(kernel1, queue, src, tmp1);

  clEnqueueNDRangeKernel(kernel2, queue, tmp1, tmp1);

  cl_mem tmp2 = clCreateBuffer(CL_READ_WRITE);
  clEnqueueNDRangeKernel(kernel2, queue, tmp1, tmp2);

  clEnqueueNDRangeKernel(kernel3, queue, tmp2, gl_buffer[i], finish_events + i);

  queue_idx = (queue_idx + 1) % kNumQueues;
}

clEnqueueReleaseGLObjects(default_queue, gl_buffers, N);
clWaitForEvents(N, finish_events);

ด้วยkNumQueues = 1แอพพลิเคชั่นนี้ใช้งานได้จริงตามที่ตั้งใจ: มันรวบรวมงานทั้งหมดไว้ในคิวคำสั่งเดียวที่จะทำงานจนเสร็จสมบูรณ์โดยที่ GPU ค่อนข้างยุ่งตลอดเวลา ฉันสามารถดูสิ่งนี้ได้โดยดูที่ผลลัพธ์ของ CodeXL Profiler:

ป้อนคำอธิบายรูปภาพที่นี่

อย่างไรก็ตามเมื่อฉันตั้งค่าkNumQueues = 2ฉันคาดหวังว่าสิ่งเดียวกันจะเกิดขึ้น แต่ด้วยการแบ่งงานอย่างเท่าเทียมกันในสองคิว หากมีสิ่งใดฉันคาดว่าแต่ละคิวจะมีคุณสมบัติเหมือนกันแยกกันเป็นหนึ่งคิว: มันเริ่มทำงานตามลำดับจนกว่าทุกอย่างจะเสร็จสิ้น อย่างไรก็ตามเมื่อใช้สองคิวฉันเห็นได้ว่าไม่ใช่งานทั้งหมดที่แบ่งเป็นสองฮาร์ดแวร์:

ป้อนคำอธิบายรูปภาพที่นี่

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

ฉันมีทฤษฎีบางอย่างเกี่ยวกับสาเหตุที่เกิดขึ้น:

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

  2. การใช้งาน OpenCL พื้นฐานไม่ได้แมปโลจิคัลคิวกับฟิสิคัลคิวและตัดสินใจเฉพาะตำแหน่งที่วางวัตถุที่รันไทม์

  3. เนื่องจากฉันใช้วัตถุ GL จึงจำเป็นต้องประสานการเข้าถึงหน่วยความจำที่จัดสรรเป็นพิเศษระหว่างการเขียน

สมมติฐานเหล่านี้เป็นจริงหรือไม่? ไม่มีใครรู้ว่าสิ่งใดที่อาจทำให้ GPU ต้องรอในสถานการณ์สองคิว ความเข้าใจใด ๆ และทั้งหมดจะได้รับการชื่นชม!


ฉันไม่สามารถหาตำแหน่งที่ระบุว่ามีคิวฮาร์ดแวร์สองรายการในคู่มือการเขียนโปรแกรม คุณสามารถโพสต์คำพูดจากเอกสารได้หรือไม่? พูดถึงบทที่ว่ามีสองคิว? จำนวนคิวฮาร์ดแวร์ที่สามารถสืบค้นได้ในรันไทม์โดยใช้ OpenCL หรือไม่
Andreas

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

คำตอบ:


2

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

สำหรับการเรนเดอร์เรียลไทม์โดยเฉพาะอย่างยิ่งกรณีที่มีสิ่งต่าง ๆ เช่นการเรนเดอร์เงาที่เบามากเกี่ยวกับการคำนวณ / เงา แต่หนักบนฮาร์ดแวร์ฟังก์ชั่นตายตัว

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

https://developer.amd.com/wordpress/media/2013/02/AMD_CodeXL_Release_Notes.pdf

สำหรับแอปพลิเคชันที่ดำเนินการถ่ายโอนข้อมูลแบบอะซิงโครนัสพร้อมกันและการดำเนินการเคอร์เนลไทม์ไลน์ที่แสดงในมุมมองเซสชันการติดตามแอปพลิเคชันจะไม่แสดงการดำเนินการเหล่านี้ซ้ำซ้อน เนื่องจากไดรเวอร์และฮาร์ดแวร์บังคับให้การดำเนินการเหล่านี้ซิงโครนัสในขณะทำโปรไฟล์ (333,981)

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