อัลกอริทึม SIMD ที่ออกแบบตั้งแต่ต้น
(mcyoung.xyz)การออกแบบอัลกอริทึม SIMD
- คำอธิบายเกี่ยวกับการทำ SIMD optimization: SIMD หมายถึง Single Instruction, Multiple Data และจำเป็นต้องคิดแบบผู้ออกแบบวงจร
- SIMD มักถูกพูดถึงบ่อยในด้านประสิทธิภาพและ HPC (การประมวลผลสมรรถนะสูง) แต่ไม่ใช่หัวข้อที่คุ้นเคยสำหรับผู้เริ่มต้น
- ในภาษาโปรแกรมส่วนใหญ่ API สำหรับการเขียนโปรแกรม SIMD ใช้งานได้ค่อนข้างยาก
- อัลกอริทึม SIMD ทำความเข้าใจได้ยากด้วยแนวคิดแบบ procedural programming และ functional programming สามารถช่วยได้
- เนื้อหาหลักกล่าวถึง vb64 ซึ่งเป็นการติดตั้งใช้งาน base64 codec โดยใช้ไลบรารี
std::simdของ Rust
ข้อจำกัดทางกายภาพ
- คอมพิวเตอร์มีอยู่ในโลกจริงและถูกจำกัดด้วยกฎทางฟิสิกส์
- ในยุคเริ่มต้นของการประมวลผล สามารถเพิ่มประสิทธิภาพได้ด้วยการซื้อคอมพิวเตอร์เครื่องใหม่
- เมื่อผลของ Dennard scaling พังทลายลง ทรานซิสเตอร์ที่เล็กลงจึงหมายถึงการใช้พลังงานมากขึ้น
- การเพิ่มจำนวนคอร์กลายเป็นแนวโน้มใหม่ สามารถเพิ่มประสิทธิภาพของ CPU ได้ด้วย multithreading แต่ต้องแลกกับ synchronization overhead
ความช้าของโค้ดเชิงกระบวนการ
- คอร์ของคอมพิวเตอร์สมัยใหม่ไม่ได้รันโค้ดทีละบรรทัด
- ผ่าน instruction-level parallelism จึงสามารถทำหลายการคำนวณพร้อมกันได้หากไม่มี data dependency
- ความขนานจะเพิ่มขึ้นเมื่อคอมไพเลอร์สามารถแก้ data hazards ได้
- การแตกแขนงและงานด้านหน่วยความจำทำให้เกิด stall ซึ่งทำให้โค้ดช้าลง
SIMD และ lane
- SIMD และเวกเตอร์มักถูกใช้แทนกันในความหมายเดียวกัน
- คำสั่ง SIMD ใช้เวกเตอร์ซึ่งเป็นอาร์เรย์ของตัวเลขขนาดคงที่เป็นหน่วยพื้นฐาน
- แต่ละองค์ประกอบของเวกเตอร์เรียกว่า lane และเวกเตอร์ SIMD โดยทั่วไปมักมีขนาดเล็ก
การดำเนินการกับเวกเตอร์จริง
- เวกเตอร์ SIMD ให้การดำเนินการที่ซับซ้อนกว่ารีจิสเตอร์ทั่วไป
- vector register รองรับการดำเนินการหลากหลาย เช่น การดำเนินการระดับบิต, arithmetic แบบแยกตาม lane, การเปรียบเทียบแยกตาม lane และ shuffle
- shuffle มีความสำคัญใน SIMD programming สำหรับการย้ายข้อมูลไปยังตำแหน่งที่เหมาะสม
intrinsic และการเลือกคำสั่ง
- การดำเนินการที่ใช้ได้ในการเขียนโค้ด SIMD จะแตกต่างกันไปตามสถาปัตยกรรม
- คอมไพเลอร์ต้องแก้ปัญหา instruction selection เพื่อเลือกว่าจะใช้คำสั่งใดสำหรับการดำเนินการที่ผู้ใช้ร้องขอ
- การเขียนโค้ด SIMD แบบพกพาเป็นเรื่องซับซ้อน แต่สามารถสร้างโค้ดที่เหมาะสมที่สุดสำหรับโปรเซสเซอร์หลายแบบได้ผ่าน runtime feature detection
การพาร์สด้วย SIMD
- สามารถใช้ SIMD เพื่อพาร์สข้อความได้ และอาจทำงานได้รวดเร็วมาก
- ตัวอย่างหนึ่งคือการติดตั้งใช้งานการถอดรหัส base64 ด้วย SIMD
- หัวใจสำคัญของการสร้างเวอร์ชัน SIMD คือการกำจัดการแตกแขนงทั้งหมด
ความเห็นของ GN⁺
สิ่งที่สำคัญที่สุดในบทความนี้คือ SIMD programming มีความสามารถในการเพิ่มประสิทธิภาพด้วยการประมวลผลข้อมูลแบบขนาน ซึ่งแตกต่างจากวิธีการเขียนโปรแกรมเชิงกระบวนการแบบเดิม SIMD มีความสำคัญอย่างมากในงานด้านการประมวลผลสมรรถนะสูง และโดยเฉพาะอย่างยิ่ง การทำความเข้าใจวิธีใช้ SIMD อย่างมีประสิทธิภาพในภาษาโปรแกรมสมัยใหม่อย่าง Rust เป็นหัวข้อที่น่าสนใจมากสำหรับวิศวกรซอฟต์แวร์ เพราะช่วยให้เรียนรู้วิธีปรับแต่งอัลกอริทึมที่ซับซ้อนและก้าวข้ามข้อจำกัดของฮาร์ดแวร์จริงได้
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
_mm256_cvtps_epu32ไม่ใช่คำสั่งของ AVX2 แต่เป็นของ AVX-512 และใน AVX1 จำนวนเต็มจะอยู่ในรูป signed ดังนั้นคำสั่งที่เกี่ยวข้องคือ_mm256_cvtps_epi32