0Pricing
CUDA Academy · บทเรียน

การขนานระดับคำสั่ง

เพิ่มงานอิสระให้แต่ละเธรด

การขนานระดับคำสั่ง เป็นบทเรียน CUDA Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน CUDA Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส CUDA Academy มีบทเรียนทั้งหมด 4 บทเรียน

ทำหลายสิ่งได้พร้อมกัน

ภายในเธรดเดียว GPU สามารถทำให้คำสั่งอิสระหลายคำสั่งอยู่ระหว่างการทำงานพร้อมกันได้ การทำงานซ้อนกันนี้เรียกว่า การทำงานขนานระดับคำสั่ง หรือ ILP

เหตุใด ILP จึงสำคัญ

การดำเนินการด้านหน่วยความจำและคณิตศาสตร์ต้องใช้หลายรอบกว่าจะเสร็จ หากแต่ละเธรดมีงานที่เป็นอิสระเพียงพอ ฮาร์ดแวร์จะซ่อน เวลาแฝง เหล่านั้นแทนที่จะหยุดรอ

การพึ่งพากันขัดขวางการทำงานซ้อนกัน

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

float a = x * 2.0f;
float b = a + 1.0f; // waits on a
float c = b * b;    // waits on b

งานอิสระไหลได้อย่างเต็มที่

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

float a = x * 2.0f;
float b = y * 2.0f; // does not need a

หนึ่งเธรด หลายสมาชิก

วิธีง่าย ๆ ในการเพิ่ม ILP คือให้แต่ละเธรดประมวลผลสมาชิกหลายตัว ผลรวมที่แยกจากกันจะกลายเป็นงานที่ เป็นอิสระ ซึ่งฮาร์ดแวร์สามารถทำงานซ้อนกันได้

out[i]     = in[i]     + 1.0f;
out[i + n] = in[i + n] + 1.0f;

ใช้ตัวสะสมหลายตัว

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

float s0 = 0, s1 = 0;
s0 += a[i];
s1 += a[i + 1];

รวมกันตอนท้าย

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

float total = s0 + s1;

ILP แลกมาด้วยรีจิสเตอร์

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

สองวิธีในการซ่อนเวลาแฝง

GPU ซ่อนการหยุดรอด้วยเธรดที่ประจำอยู่จำนวนมากและด้วย ILP ภายในแต่ละเธรด ILP ที่ดีสามารถทำให้ SM ทำงานอยู่ได้ แม้ระดับการครอบครองจะไม่สูง

ค้นหาสายโซ่ที่ยาว

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

อย่าทำมากเกินไป

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

ตรวจสอบอย่างรวดเร็ว

การลดค่าของคุณรวมผลลงในตัวแปรเดียวทุกครั้งที่วนซ้ำ คุณจะเพิ่ม ILP ได้อย่างไร

สรุป: ทำงานซ้อนกันภายในเธรด

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

คำถามที่พบบ่อย

บทเรียน “การขนานระดับคำสั่ง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การขนานระดับคำสั่ง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส CUDA Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส CUDA Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การขนานระดับคำสั่ง”

เพิ่มงานอิสระให้แต่ละเธรด คุณปฏิบัติ CUDA Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน CUDA Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน CUDA Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การขนานระดับคำสั่ง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน CUDA Academy นี้ได้ไหม

ได้ บทเรียน CUDA Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การขนานระดับคำสั่ง
  2. คลี่ลูปด้วย #pragma unroll
  3. โหลดแบบเวกเตอร์ด้วย float4
  4. แรงกดดันของรีจิสเตอร์และการสปิล
← กลับไปที่ CUDA Academy