2 คะแนน โดย GN⁺ 2025-02-23 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

บทนำ

  • ยินดีต้อนรับสู่บทเรียนภาษาแอสเซมบลีของ FFmpeg บทเรียนนี้จะปูพื้นฐานเกี่ยวกับการเขียนภาษาแอสเซมบลีใน FFmpeg

ความรู้ที่จำเป็น

  • จำเป็นต้องมีความรู้ภาษา C โดยเฉพาะเรื่องพอยน์เตอร์
  • จำเป็นต้องมีความรู้คณิตศาสตร์ระดับมัธยมปลาย เช่น สเกลาร์และเวกเตอร์ การบวก การคูณ เป็นต้น

ภาษาแอสเซมบลีคืออะไร?

  • ภาษาแอสเซมบลีคือภาษาการเขียนโปรแกรมที่เขียนโค้ดซึ่งสอดคล้องโดยตรงกับคำสั่งที่ CPU ประมวลผล
  • โค้ดแอสเซมบลีส่วนใหญ่ของ FFmpeg เป็นแบบ SIMD (Single Instruction Multiple Data) ซึ่งเรียกอีกอย่างว่าเวกเตอร์โปรแกรมมิง
  • SIMD เหมาะสำหรับการประมวลผลข้อมูลจำนวนมากที่เก็บเรียงต่อกันในหน่วยความจำ เช่น ภาพ วิดีโอ และเสียง

ทำไมจึงเขียนด้วยภาษาแอสเซมบลี?

  • เพื่อเพิ่มความเร็วในการประมวลผลมัลติมีเดีย การเขียนเป็นแอสเซมบลีสามารถเพิ่มความเร็วได้มากกว่า 10 เท่า
  • ใน FFmpeg จะเขียนโค้ดแอสเซมบลีโดยตรงแทนการใช้ intrinsic โดยทั่วไป intrinsic จะช้ากว่าแอสเซมบลีที่เขียนด้วยมือราว 10-15%

ประเภทของภาษาแอสเซมบลี

  • บทเรียนนี้มุ่งเน้นที่ภาษาแอสเซมบลี x86 แบบ 64 บิต ซึ่งรู้จักกันในชื่อ amd64 และทำงานได้บน Intel CPU เช่นกัน
  • ไวยากรณ์แอสเซมบลี x86 มีสองแบบคือ AT&T และ Intel และจะใช้ไวยากรณ์แบบ Intel

เอกสารประกอบ

  • การเขียนโปรแกรมแอสเซมบลีของ FFmpeg มุ่งเน้นการประมวลผลภาพประสิทธิภาพสูงและมีแนวทางที่เป็นเอกลักษณ์
  • ไดอะแกรมจากหนังสือ "The Art of 64-bit assembly" อาจช่วยได้

รีจิสเตอร์

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

รีจิสเตอร์อเนกประสงค์

  • รีจิสเตอร์อเนกประสงค์ (GPR) สามารถเก็บข้อมูลหรือที่อยู่หน่วยความจำได้ ในโค้ดแอสเซมบลีของ FFmpeg นั้น GPR ทำหน้าที่เป็นฐานรองรับเป็นหลัก

เวกเตอร์รีจิสเตอร์

  • เวกเตอร์รีจิสเตอร์ (SIMD) เก็บองค์ประกอบข้อมูลได้หลายตัว และมีเวกเตอร์รีจิสเตอร์หลายประเภท
  • การคำนวณส่วนใหญ่ของการบีบอัดและคลายการบีบอัดวิดีโอเป็นแบบจำนวนเต็ม

การ include x86inc.asm

  • x86inc.asm เป็นเลเยอร์นามธรรมแบบเบาที่ใช้ใน FFmpeg, x264 และ dav1d เพื่อช่วยให้งานของโปรแกรมเมอร์แอสเซมบลีง่ายขึ้น

โค้ดแอสเซมบลีสเกลาร์แบบง่าย

  • อธิบายการทำงานของโค้ดแอสเซมบลีสเกลาร์ผ่านโค้ดตัวอย่าง

ทำความเข้าใจฟังก์ชันเวกเตอร์พื้นฐาน

  • อธิบายความหมายของแต่ละบรรทัดผ่านตัวอย่างฟังก์ชัน SIMD แรก
  • ใช้คำสั่งอย่าง movu, paddb เพื่อดำเนินการเวกเตอร์
  • ฟังก์ชันจะแก้ไขข้อมูลของอาร์กิวเมนต์และไม่ส่งคืนค่า

1 ความคิดเห็น

 
GN⁺ 2025-02-23
ความคิดเห็นจาก Hacker News
  • มีแหล่งข้อมูลอีกชิ้นในหัวข้อเดียวกันคือกรณีศึกษาของ FFmpeg และ dav1d

    • FFmpeg ถูกใช้งานบ่อย จึงถือเป็นกรณีใช้งานที่ชัดเจน
    • dav1d ถูกใช้ในเบราว์เซอร์หลักและระบบปฏิบัติการ Android โดยปัจจัยสำคัญอย่างหนึ่งของความสำเร็จคือ SIMD ที่เขียนด้วยมือ
    • โค้ดบางส่วนของ dav1d ถูกรันวันละหลายล้านล้านครั้ง จึงต้องทำงานให้เร็วที่สุดเท่าที่จะเป็นไปได้
    • ความต่างด้านประสิทธิภาพระหว่าง SIMD ที่เขียนด้วยมือกับ SIMD ที่คอมไพเลอร์สร้างให้ อาจสูงสุดได้ถึง 50%
    • เพื่อคงรักษาเทคนิคเหล่านี้ไว้ แหล่งข้อมูลอย่าง FFmpeg Assembly Language School จึงมีความสำคัญ
  • คิดว่าการใช้ intrinsic น่าจะมีคุณค่ามากกว่าการเขียน assembly เอง แต่การอ่านเรื่องนี้มีประโยชน์มาก

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

    • ถ้ามีคู่มือนี้ตอนที่สนใจงานระดับล่างมากกว่านี้ก็คงดี
  • สงสัยว่าการเรียนหรือการลงมือทำ assembly มี "ความสนุก" อยู่ในตัวหรือไม่

    • อยากรู้ว่ามันสนุกแบบเดียวกับ LISP หรือ RISC-V หรือเป็นแบบ COBOL ที่เรียนเพื่อใช้กับระบบและงานเฉพาะทาง
    • ในงานประจำวันไม่มีเหตุผลให้ใช้ assembly แต่ก็สงสัยว่าคุ้มไหมที่จะลงทุนเวลาเพราะความสนุก
  • คำต่อท้าย "q" บ่งบอกขนาดของพอยน์เตอร์ ซึ่งบนระบบ 64 บิตคือ 8

    • รู้สึกว่าประโยคนี้ทำให้สับสน
    • "i.e" ควรเขียนเป็น "i.e.," และ "(" ควรเป็นวงเล็บเปิด
    • "sizeof" ไม่ได้คืนค่าพอยน์เตอร์
  • ชื่นชมการอ้างอิงถึง K&R

    • เป็นหนังสือเล่มแรกที่ซื้อเพื่อเรียนรู้ C และการเขียนโปรแกรม
    • ตอนแรกเรียน C++ แต่รู้สึกว่านามธรรมเกินไปจนเข้าใจได้ยาก
  • ข้อเสียของการใช้ assembly คือโค้ดผูกติดกับสถาปัตยกรรม

    • ต้องเขียนโค้ดแยกกันสำหรับ x86, arm และ x86_64
    • ยังไม่มีวิธีที่ดีในการเขียนโค้ด SIMD แบบพกพา
    • Rust กำลังทำให้ SIMD API แบบพกพาเสถียร ส่วน Zig ก็มีการรองรับ SIMD แต่ FFmpeg อาจยังไม่พอใจกับความเร็วอยู่ดี
  • ความไม่เห็นด้วยกับ inline assembly ทำให้สับสน

    • inline assembly ดูเหมือนจะมีประสิทธิภาพกว่าการเรียกฟังก์ชัน assembly
  • เนื้อหานี้สมบูรณ์แบบ

    • เคยรู้จัก x86 assembly ในยุค 386 แต่โปรเซสเซอร์ที่ล้ำหน้ากว่านั้นซับซ้อนเกินไป
    • อยากเรียนรู้ SIMD บน CPU รุ่นใหม่ให้มากขึ้น
  • สงสัยว่ายังจริงอยู่ไหมที่ assembly เร็วกว่า C ถึง 10 เท่า

    • สงสัยว่าคอมไพเลอร์พัฒนามาถึงทางตันจนไม่สามารถเข้าใกล้ assembly ที่เขียนด้วยมือได้หรือไม่