Parallel Systems · บทที่ 3 จาก 9

Types of Parallelism

ก่อนแบ่งงานให้หน่วยประมวลผลหลายตัว ต้องรู้ก่อนว่างานของเรา "แบ่งได้แบบไหน" — บทนี้จัดประเภทของพารัลเลลิซึมออกเป็น 3 แบบที่เป็นรากฐานของทุกโมเดลการเขียนโปรแกรมขนานที่จะเรียนในบทที่ 5

📚
สังเคราะห์จากเอกสาร "Parallelism" (2110732 Parallel Computing) — กรอบคิด 3 ประเภทนี้เป็นรากฐานที่ไม่เปลี่ยนแปลง แม้เทคโนโลยีที่ใช้ implement จะเปลี่ยนไปมากตั้งแต่ยุคที่เอกสารต้นฉบับเขียนขึ้น

1สามประเภทของพารัลเลลิซึม

Data Parallelism

ทำoperation เดียวกันกับข้อมูลหลายชิ้นพร้อมกัน — แต่ละหน่วยประมวลผลรับผิดชอบข้อมูลคนละส่วน แต่ทำงานแบบเดียวกันทั้งหมด

Functional (Task) Parallelism

ทำoperation ต่างกันพร้อมกัน โดยแต่ละหน่วยประมวลผลรับผิดชอบงานคนละหน้าที่ที่ไม่ขึ้นต่อกัน

Pipelining

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

2ตัวอย่างเปรียบเทียบ: งานสวน

เอกสารต้นฉบับใช้อุปมาการดูแลสวน (ตัดหญ้า Mow, เล็มขอบ Edge, กำจัดวัชพืช Weed, รดน้ำ/เปิดสปริงเกลอร์) เพื่อแยกความต่างของ 3 ประเภทให้เห็นภาพชัดเจน

ประเภทวิธีแบ่งงานสวน
Data Parallelismแบ่งสวนเป็น 4 โซน ให้คนงาน 4 คนทำหน้าที่เดียวกันทั้งหมดคือตัดหญ้า คนละโซน — ทำงานพร้อมกัน เสร็จเร็วขึ้นเป็นสัดส่วนกับจำนวนคน
Functional Parallelismคนงาน 4 คนทำหน้าที่ต่างกันพร้อมกัน — คนหนึ่งตัดหญ้า อีกคนเล็มขอบ อีกคนกำจัดวัชพืช อีกคนรดน้ำ (ถ้างานเหล่านี้ไม่ขึ้นต่อกัน ทำพร้อมกันได้ทันที)
Pipeliningสวนแปลงหนึ่งต้องทำตามลำดับ: ตัดหญ้า → เล็มขอบ → กำจัดวัชพืช → รดน้ำ — ขณะที่คนงานคนที่ 2 กำลังเล็มขอบแปลงที่ 1 คนงานคนที่ 1 เริ่มตัดหญ้าแปลงที่ 2 ได้แล้ว (ไม่ต้องรอให้แปลงที่ 1 เสร็จทั้งหมดก่อน)
ข้อจำกัดสำคัญของ Pipelining
ต้องตรวจสอบก่อนว่าไม่มีลำดับที่สลับได้ตามใจ — เช่น "ห้ามกำจัดวัชพืชจนกว่าอีก 3 งานจะเสร็จ" (dependency ข้าม stage) จะทำให้ pipeline หยุดชะงัก คล้ายกับ hazard ในบทที่ 2 ทุกประการ — pipelining ที่ดีต้องมี stage ที่เป็นอิสระจากกันมากที่สุด

3Data Dependence Graph: เครื่องมือหาว่าอะไรขนานได้

แนวคิด
กราฟมีทิศทาง (directed graph) ที่แต่ละ vertex คือหนึ่งงานย่อย (task) และแต่ละเส้นเชื่อม (edge) คือความสัมพันธ์ "ต้องเสร็จก่อน" — Task ที่ไม่มีเส้นเชื่อมระหว่างกันเป็นอิสระต่อกัน และทำขนานกันได้ทันที
ระดับความละเอียด (Granularity)ความหมาย
Coarse-grainแบ่งเป็น task ก้อนใหญ่ระดับโปรแกรมหรือฟังก์ชัน — overhead การประสานงานต่ำ (สื่อสารไม่บ่อย) แต่โอกาสหา independent task ได้น้อยกว่า
Fine-grainแบ่งเป็น task เล็กระดับคำสั่งหรือ loop iteration — โอกาสขนานได้สูงกว่า แต่ overhead การประสานงาน (สื่อสาร/ซิงโครไนซ์) สูงตามไปด้วย เพราะต้องประสานงานกันบ่อยกว่ามาก
ข้อควรจำสำหรับสอบ
ไม่มีระดับ granularity ที่ "ถูกที่สุด" ตายตัว — ต้องเลือกให้เข้ากับ overhead ของระบบที่ใช้จริง (ดูรายละเอียดสูตร T = Tcomp + Tpar + Tinteract ในบทที่ 6) ยิ่งแบ่งละเอียดเกินไปในระบบที่ overhead การสื่อสารสูง (เช่น ข้ามเครื่องผ่านเครือข่าย) ยิ่งขาดทุนมากกว่าได้ — นี่คือเหตุผลที่ MPI (บทที่ 5) มักนิยมงานแบบ coarse-grain ในขณะที่ GPU (ก็บทที่ 5 เช่นกัน) ออกแบบมาให้รองรับงาน fine-grain นับล้าน thread ได้เพราะ overhead ต่อ thread ต่ำมาก

4แนวคิดทั้งสามปรากฏในเครื่องมือปัจจุบันอย่างไร

แล้ว · กรอบคิดในเอกสารต้นฉบับ
ตอนนี้ · เครื่องมือที่ implement กรอบคิดเดียวกัน
Data Parallelism — อธิบายด้วยตัวอย่าง loop แบ่งงานแบบ SIMD
GPU/CUDA (บทที่ 5) คือ data parallelism ระดับใหญ่ที่สุดที่ใช้งานจริง — เธรดหลักพันตัวรัน kernel เดียวกันกับข้อมูลคนละส่วน โมเดล MapReduce/Apache Spark ก็คือ data parallelism ระดับ cluster (map ทำ operation เดียวกันกับข้อมูลแต่ละก้อนแบบขนาน)
Functional Parallelism — อธิบายด้วยตัวอย่างงานสวนที่ทำหน้าที่ต่างกัน
Thread pool / async task ในภาษาโปรแกรมสมัยใหม่ (เช่น Python concurrent.futures, JavaScript Promise.all) และ workflow orchestration (เช่น Apache Airflow ที่นิยาม task graph ตรงกับ Data Dependence Graph ในหัวข้อ 3 โดยตรง) คือ functional parallelism ที่ implement จริงในระบบ production
Pipelining — อธิบายด้วยตัวอย่างระดับคำสั่งซีพียู (บทที่ 2)
แนวคิดเดียวกันขยายไปถึงระดับระบบ: CI/CD pipeline (build → test → deploy), data pipeline (Apache Beam/Kafka Streams ที่แต่ละ stage ประมวลผล record คนละชุดพร้อมกัน), และ video encoding pipeline ที่แบ่งเฟรมเป็นชุด ๆ ผ่านหลาย stage การเข้ารหัสพร้อมกัน — หลักการ "stage ที่เป็นอิสระต่อกันมากที่สุด" จากหัวข้อ 2 ยังใช้ได้เป๊ะกับทุกตัวอย่างเหล่านี้
ข้อสังเกตสำคัญ
สิ่งที่เปลี่ยนไปตั้งแต่เอกสารต้นฉบับไม่ใช่ "ประเภทของพารัลเลลิซึม" (ยังมีแค่ 3 แบบนี้เหมือนเดิม) แต่คือสเกลที่นำไปใช้จริง — จากเดิมที่พูดถึงระดับคำสั่งซีพียูหรือ loop เดียว ขยายไปถึงระดับ cluster ทั้งดาต้าเซ็นเตอร์ (บทที่ 7-9) โดยที่กรอบคิดพื้นฐานเรื่อง dependency graph และ granularity ยังคงใช้วิเคราะห์ได้เหมือนเดิมทุกประการ
คำถามซ้อมสอบ
  1. แยกแยะ data parallelism, functional parallelism, และ pipelining พร้อมยกตัวอย่างของตัวเองที่ไม่ใช่ตัวอย่างงานสวน
  2. อธิบายว่าทำไม pipelining ถึงต้องการให้แต่ละ stage มีความเป็นอิสระต่อกันมากที่สุด และจะเกิดอะไรขึ้นถ้าไม่เป็นเช่นนั้น
  3. อธิบาย coarse-grain กับ fine-grain parallelism พร้อม trade-off ของแต่ละแบบ
  4. ยกตัวอย่างเครื่องมือหรือเทคโนโลยีสมัยใหม่ที่ implement data parallelism, functional parallelism, และ pipelining อย่างละหนึ่งตัวอย่าง (นอกเหนือจากที่กล่าวถึงในบทเรียน)
  5. อธิบายว่าทำไม MPI จึงมักเหมาะกับงาน coarse-grain ในขณะที่ GPU เหมาะกับงาน fine-grain โดยเชื่อมโยงกับ overhead ของแต่ละแพลตฟอร์ม

5Data Parallelism: สูตรเดียวกัน ข้อมูลคนละส่วน

Data parallelism เหมาะเมื่อข้อมูลจำนวนมากผ่าน operation ชุดเดียวกันหรือคล้ายกัน เช่น ปรับสีทุก pixel คูณ matrix แต่ละ block หรือคำนวณ gradient จากแต่ละตัวอย่าง ข้อมูลถูกแบ่งเป็น partition แล้ว worker ทำงานชนิดเดียวกันบนส่วนของตน

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

รูปแบบย่อยที่พบบ่อย

คำว่า data-parallel ไม่ได้แปลว่าไม่มี dependency Reduction และ scan ต้องออกแบบ tree structure ส่วน stencil ต้องแลก halo หรือ boundary ระหว่าง partition สิ่งที่เหมือนกันคือเราจัดงานโดยเริ่มจากการแบ่ง data domain

6Functional หรือ Task Parallelism: งานคนละอย่างทำพร้อมกัน

Functional parallelism แยกตามกิจกรรม เช่น task หนึ่งอ่านไฟล์ task หนึ่งถอดรหัส และอีก task วิเคราะห์ข้อมูล เหมาะเมื่อระบบมีงานหลายชนิดที่เป็นอิสระหรือคาบเกี่ยวกันได้

คุณสมบัติData ParallelismTask Parallelism
สิ่งที่แบ่งข้อมูลคนละส่วนหน้าที่หรือ task คนละชนิด
โค้ดของ workerเหมือนหรือคล้ายกันอาจต่างกันมาก
ปัญหาหลักPartition, boundary และ reductionDependency, scheduling และ resource ต่างชนิด
ตัวอย่างGPU kernel, matrix block, image tileGame engine, DAG workflow, web request subtasks

ระบบจริงมักผสมกัน เช่น pipeline หนึ่ง stage ทำ inference บน GPU แบบ data-parallel ขณะที่อีก stage ทำ preprocessing บน CPU แบบ task-parallel การจัดประเภทมีไว้ช่วยคิด ไม่ใช่บังคับให้ระบบอยู่ได้เพียงช่องเดียว

7Pipeline Parallelism: หลายขั้นตอนทำงานคนละชิ้นพร้อมกัน

Pipeline แบ่งงานเป็น stages งานชิ้นแรกเดินจาก stage 1 ไป 2 ไป 3 ขณะ stage 2 ทำชิ้นแรก stage 1 เริ่มชิ้นที่สองได้ เมื่อ pipeline เต็ม throughput ขึ้นกับ stage ที่ช้าที่สุด

เวลาคร่าว ๆ ของ pipeline
T ≈ Σ latency(stage) + (n − 1) · max latency(stage)
ส่วนแรกคือเวลาเติม pipeline ส่วนงานชิ้นถัดไปออกได้ตามจังหวะของ stage ที่ช้าที่สุด หาก stage หนึ่งใช้ 10 ms ต่อชิ้น ต่อให้ stage อื่นใช้ 1 ms throughput ก็ถูกจำกัดใกล้ 100 ชิ้นต่อวินาที
สายการผลิต
ล้างขวด 1 นาที เติมน้ำ 4 นาที และติดฉลาก 1 นาที เมื่อทำต่อเป็น pipeline ขั้นเติมน้ำคือคอขวด การเพิ่มคนล้างขวดไม่ช่วย throughput ต้องเพิ่มเครื่องเติมน้ำหรือแบ่ง batch ในขั้นนั้น

8Latency, Throughput และจำนวนงานที่ค้างอยู่ใน Pipeline

Pipeline เพิ่ม throughput โดยให้หลายชิ้นอยู่ในระบบพร้อมกัน แต่ latency ของชิ้นหนึ่งยังรวมเวลาผ่านทุก stage และอาจเพิ่มจาก queue ถ้าส่งงานเร็วกว่าคอขวดรับได้ Queue จะโตจนใช้ memory หมดหรือ deadline หลุด

Backpressure ให้ downstream แจ้ง upstream ให้ชะลอเมื่อรับไม่ทัน เปรียบเหมือนร้านอาหารหยุดรับบัตรคิวชั่วคราวเมื่อครัวเต็ม ถ้าปล่อยให้รับ order ไม่จำกัด ตัวเลขหน้าเคาน์เตอร์อาจดูว่ารับงานได้เร็ว แต่ลูกค้ารออาหารนานขึ้นเรื่อย ๆ

Buffer ใหญ่ซ่อนปัญหา ไม่ได้แก้คอขวด
Queue ใหญ่ช่วยรับ burst ชั่วคราว แต่ถ้า arrival rate สูงกว่า service rate ต่อเนื่อง backlog ต้องโตไม่สิ้นสุด วิธีแก้คือเพิ่ม capacity ของ stage ช้า ลดงาน หรือควบคุมอัตรารับเข้า

9Dependency มีหลายชนิด

ชนิดความหมายขนานได้หรือไม่
Flow / RAWB อ่านค่าที่ A เขียนB ต้องรอ A เป็น dependency จริง
Anti / WARB เขียนตำแหน่งที่ A ยังต้องอ่านอาจแก้ด้วยการเปลี่ยนชื่อหรือใช้ buffer คนละชุด
Output / WAWA และ B เขียนตำแหน่งเดียวกันต้องรักษาลำดับ หรือแยกผลแล้วรวม
Controlงานหนึ่งเกิดหรือไม่ขึ้นกับเงื่อนไขอาจ speculate หรือแยก task ตามเส้นทาง
Resourceแย่งทรัพยากรเดียว เช่น port หรือ lockไม่ใช่ dependency ของคำตอบ แต่บังคับให้รอใน implementation

การแยก true dependency ออกจาก name/resource dependency สำคัญ เพราะสองแบบหลังอาจหายได้เมื่อออกแบบ storage หรือ schedule ใหม่ หากเห็นการรอแล้วสรุปว่า algorithm ขนานไม่ได้ เราอาจยอมแพ้เร็วเกินไป

10Loop-Carried Dependency: อุปสรรคของ Parallel Loop

Iteration ของ loop จะขนานได้เมื่อ iteration i ไม่ต้องใช้ผลที่ iteration ก่อนหน้ากำลังสร้าง ตัวอย่าง y[i]=x[i]*2 independent แต่ a[i]=a[i-1]+x[i] มี dependency ต่อเนื่อง

อย่างไรก็ตาม prefix sum ที่ดูเป็นสายยาวสามารถเปลี่ยน algorithm เป็น tree-based scan ได้ ใช้หลายรอบแต่เปิด parallelism มากขึ้น นี่เป็นตัวอย่างว่าความขนานไม่ได้เป็นเพียงคุณสมบัติของ “ปัญหา” แต่ขึ้นกับ algorithm ที่เลือกแทนปัญหานั้นด้วย

คำถามก่อนใส่ parallel for
แต่ละ iteration อ่านและเขียนตำแหน่งใด มี alias หรือไม่ ลำดับผลลัพธ์มีผลต่อ floating-point rounding หรือไม่ และถ้ามี reduction runtime รวมผลอย่างไร การใส่ pragma ไม่ได้ทำให้ dependency หายไป

11Data Dependence Graph จากรูปวาดสู่การวัด

ใน DAG แต่ละ node คือ task และ edge คือเงื่อนไขว่าปลายทางเริ่มได้หลังต้นทางเสร็จ จากกราฟเดียวกันเราหาได้ทั้ง work, critical path และระดับ parallelism ที่มีในแต่ละช่วง

ขอบเขต
Speedup สูงสุดจากโครง DAG ≤ T₁ / T∞
ถ้า work 1,000 หน่วยแต่ critical path 100 หน่วย average parallelism คือ 10 ต่อให้มี 100 cores ก็ไม่มีเหตุผลคาดหวัง speedup 100 เท่าจาก DAG เดิม

12Granularity: Task ใหญ่จัดกับเล็กจัดต่างก็มีปัญหา

Coarse-grained task มีงานต่อชิ้นมาก ต้นทุน schedule และ communication ต่ำเมื่อเทียบกับ computation แต่แบ่งโหลดได้หยาบ Fine-grained task เปิด concurrency และ balance ได้ดี แต่ runtime ต้องจัดการ task จำนวนมาก

Granularityข้อดีความเสี่ยง
หยาบLocality ดี overhead ต่ำTask น้อยกว่า core และเกิด straggler
ละเอียดBalance ง่าย มี ready task มากQueue, scheduling และ synchronization แพง
ปรับแบบ adaptiveรวม task เมื่อเล็ก แตกเพิ่มเมื่อหนักRuntime และการคาดเดาต้นทุนซับซ้อน

ค่าที่เหมาะขึ้นกับ architecture ด้วย Task 10 microseconds อาจเหมาะกับ thread pool ในเครื่อง แต่เล็กเกินไปสำหรับการส่งผ่าน network ไป cluster worker

13Regular กับ Irregular Parallelism

งาน regular มีรูปแบบข้อมูลและเวลาต่อ task คาดเดาได้ เช่น dense matrix หรือ image convolution จัด partition แบบ static และใช้ SIMD/GPU ได้ดี งาน irregular เช่น graph traversal, sparse matrix หรือ branch-and-bound มี degree, memory access และขนาด subtree ต่างกัน ต้องใช้ dynamic scheduling มากขึ้น

แจกหนังสือกับตามหาคนหาย
แจกหนังสือให้นักเรียนทุกคนเป็นงาน regular รู้จำนวนและขั้นตอนล่วงหน้า ส่วนตามหาคนหายในเมืองเป็น irregular แต่ละเบาะแสแตกแขนงไม่เท่ากันและบางทีมจบเร็วกว่า เราต้องปรับทีมตามข้อมูลใหม่ ไม่ใช่แบ่งแผนที่เท่ากันแล้วหวังว่างานเท่ากัน

Irregular ไม่ได้แปลว่าขนานไม่ได้ แต่ locality และ balance เป็นปัญหาหลัก เครื่องมืออย่าง work stealing, graph partitioning และ asynchronous traversal จึงมีบทบาทมาก

14Reduction: หลายคำตอบย่อยรวมเป็นคำตอบเดียว

การรวมผลแบบลำดับมี critical path O(n) แต่ tree reduction รวมเป็นคู่ ๆ ได้ O(log n) stages หาก operation associative เช่นผลรวมจำนวนเต็มในทางคณิตศาสตร์

Floating point ไม่ associative แบบสมบูรณ์
(a+b)+c อาจไม่เท่ากับ a+(b+c) เพราะมีการปัดเศษ Parallel reduction เปลี่ยนลำดับการรวม จึงอาจได้เลขท้ายต่างจาก serial version ไม่จำเป็นต้องเป็น bug แต่ต้องกำหนด tolerance และ reproducibility requirement

เทคนิคอย่าง pairwise summation หรือ compensated summation ช่วยความแม่นยำ แต่เพิ่ม work การออกแบบต้องเลือกระหว่าง speed, accuracy และ deterministic result ตามบริบท

15Scatter, Gather และ All-to-All: รูปแบบการสื่อสารก็เป็นส่วนของ Algorithm

งาน Machine Learning แบบ data-parallel มักคำนวณ gradient ในแต่ละ accelerator แล้ว all-reduce ผล การเพิ่ม GPU จึงลด compute ต่อ GPU แต่ communication ของ gradient อาจกลายเป็นคอขวด รูป parallelism และ collective communication ต้องออกแบบร่วมกัน

16Synchronization: รอเท่าที่ความหมายจำเป็น

กลไกใช้เมื่อต้นทุน/ความเสี่ยง
Barrierทุก task ต้องจบรอบก่อนเริ่มรอบใหม่Worker เร็วรอ worker ช้า
Lockป้องกัน critical section หรือ shared invariantContention, deadlock และ convoy
Atomicอัปเดตค่าขนาดเล็กแบบ indivisibleCache-line contention หากทุก thread แตะจุดเดียว
Message/Dataflowเริ่มงานเมื่อ input เฉพาะของตนพร้อมRuntime ซับซ้อน แต่ลด global waiting

Global barrier เข้าใจง่ายแต่เปลี่ยน straggler หนึ่งตัวให้ทุกคนรอ Dataflow scheduling ปล่อย task ที่ input พร้อมเดินต่อได้ จึงเหมาะกับ DAG ที่แต่ละแขนมีเวลาต่างกัน

17Nested และ Hybrid Parallelism

โปรแกรมสมัยใหม่ใช้ parallelism ซ้อนหลายระดับ เช่น MPI แบ่งงานระหว่างเครื่อง OpenMP แบ่งงานระหว่าง core และ SIMD ทำหลาย element ต่อ instruction หรือ Spark แบ่ง partition ระหว่าง executor ขณะที่ library ภายในใช้ multithreaded BLAS

Oversubscription
ถ้า MPI 8 processes ต่างสร้าง 16 threads บนเครื่อง 32 cores เราได้ 128 runnable threads แย่ง CPU กันโดยไม่ตั้งใจ Library ที่สร้าง thread ภายในอาจซ้อนกับ parallelism ชั้นนอก จึงต้องกำหนดจำนวน thread และ affinity อย่างรู้โครงสร้างทั้งหมด

18Parallelism ใน Deep Learning

รูปแบบแบ่งอะไรข้อจำกัดหลัก
Data parallelแต่ละ device รับ mini-batch คนละส่วน โมเดลเหมือนกันGradient synchronization และ batch-size scaling
Model/Tensor parallelแบ่ง layer หรือ tensor ใหญ่ข้าม deviceCommunication ถี่และ placement ซับซ้อน
Pipeline parallelแบ่งกลุ่ม layers เป็น stagesPipeline bubble และ balance ระหว่าง stages
Expert parallelกระจาย experts ใน Mixture-of-ExpertsRouting imbalance และ all-to-all traffic

ระบบฝึกโมเดลขนาดใหญ่จึงไม่ได้เลือก parallelism แบบเดียว แต่ประกอบหลายมิติให้ตรงกับ memory capacity, bandwidth และ topology ของ cluster

19กรอบเลือกประเภท Parallelism

  1. วาดข้อมูลและ dependency ก่อนเลือกเครื่องมือ
  2. ถ้า operation ซ้ำบนข้อมูลจำนวนมาก ให้เริ่มพิจารณา data parallelism
  3. ถ้ามีงานคนละชนิดที่อิสระ ให้พิจารณา task parallelism
  4. ถ้าข้อมูลไหลผ่านหลายขั้นและมีหลายชิ้นต่อเนื่อง ให้พิจารณา pipeline
  5. ตรวจ stage/task ที่ช้าที่สุดและ pattern การสื่อสาร
  6. ออกแบบ granularity ให้ computation มากพอชดเชย overhead
  7. ค่อยเลือก thread, process, GPU, MPI หรือ framework
แนวคิดสำคัญ
ประเภท parallelism เป็นภาษาสำหรับอธิบายโครงงาน ไม่ใช่ชื่อผลิตภัณฑ์ CUDA ใช้ data และ task parallelism ได้ Spark มีทั้ง dataflow DAG และ pipeline ภายใน stage เครื่องมือหนึ่งจึงรองรับหลาย pattern และ pattern หนึ่งก็ implement ได้หลายเครื่องมือ

20กรณีศึกษา: ระบบประมวลผลวิดีโอ

  1. วิดีโอหลายไฟล์ประมวลผลพร้อมกันเป็น task parallelism ระดับ job
  2. แต่ละไฟล์ผ่าน decode → filter → inference → encode เป็น pipeline
  3. Filter แต่ละ frame ใช้ data parallelism บน pixel/GPU
  4. Inference หลาย frame รวมเป็น batch เพื่อใช้ accelerator คุ้มขึ้น
  5. เขียนผลแยกไฟล์ ลด shared lock และรวม metadata ภายหลัง

คอขวดอาจย้ายตาม configuration ถ้า decode ช้า GPU จะว่าง ถ้า batch ใหญ่ latency ต่อ frame สูงขึ้น ถ้า encode ช้า queue หลัง inference โต การออกแบบจึงต้องวัดทั้ง stage time, utilization, queue และ end-to-end latency

21แล็บและแบบฝึกที่แนะนำ

แล็บ 1: DAG Scheduling
ให้นักศึกษาสร้าง DAG 15–20 tasks ที่มีเวลาต่างกัน คำนวณ work, critical path และ average parallelism จากนั้นทดลอง schedule บน 2, 4 และ 8 workers เปรียบเทียบ static queue กับ work stealing
แล็บ 2: Pipeline
สร้าง pipeline สาม stages โดยจงใจให้ stage กลางช้า วัด latency, throughput และ queue length จากนั้นเพิ่ม worker เฉพาะ stage คอขวดและเพิ่ม backpressure
แบบฝึกออกแบบ
เลือกระบบหนึ่ง เช่น ETL, image analytics หรือ training pipeline แล้วทำเครื่องหมายแต่ละส่วนว่าเป็น data, task หรือ pipeline parallelism พร้อมวาด communication pattern และจุด synchronization

22สรุปและขั้นตอนถัดไป

Data, task และ pipeline parallelism เป็นสามเลนส์หลักสำหรับมองงาน แต่ระบบจริงผสมกันได้ สิ่งสำคัญกว่าชื่อหมวดคือ dependency, granularity, load balance, communication และ synchronization เพราะสิ่งเหล่านี้กำหนดว่า parallelism ที่เห็นบนกระดาษจะกลายเป็น speedup บนเครื่องจริงหรือไม่

บทถัดไปจะถามต่อว่า เมื่อรู้รูปแบบของงานแล้ว ฮาร์ดแวร์ชนิดใดเหมาะกับมัน Shared memory, distributed memory, vector processor, GPU, cluster และ NUMA ต่างเปิด parallelism และคิดราคาการย้ายข้อมูลคนละแบบครับ