4 คะแนน โดย GN⁺ 2024-10-19 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

การใช้ประโยชน์จาก concurrency และ parallelism ของ Go

  • แนะนำโปรเจกต์ที่ต้องการเพิ่มความสามารถในการคำนวณตัวเลขด้วยการใช้ประโยชน์จาก concurrency และ parallelism ของ Go
  • สามารถใช้คำสั่ง SIMD (Same Instruction Multiple Data) เพื่อทำการคำนวณแบบขนานในระดับฮาร์ดแวร์ได้
  • คอมไพเลอร์ของ Go ไม่ได้ใช้ SIMD และเนื่องจากหาแพ็กเกจ SIMD แบบ general-purpose ที่เหมาะสมไม่ได้ จึงตัดสินใจพัฒนาแพ็กเกจขึ้นมาเอง

ภาษาแอสเซมบลี Plan9

  • Go ใช้ภาษาแอสเซมบลีของตัวเองชื่อ Plan9 โดยเป็นการนำคำสั่งและรีจิสเตอร์ของแพลตฟอร์มเฉพาะมาปรับเล็กน้อยแล้วใช้งาน
  • x86 Plan9 และ ARM Plan9 แตกต่างกัน
  • อธิบายวิธีใช้งานพื้นฐานผ่านตัวอย่างง่าย ๆ ของ Plan9

ตัวอย่าง Plan9

  • อธิบายการประกาศฟังก์ชันพื้นฐานและวิธีใช้งานของ Plan9 ผ่านไฟล์ AddInts_amd64.s และ main.go
  • อธิบายวิธีเก็บอาร์กิวเมนต์ของฟังก์ชันและค่าที่ส่งกลับไว้บนสแตกตาม calling convention ของ Go

แผนการออกแบบแพ็กเกจ

  • ออกแบบแพ็กเกจที่ให้เลเยอร์ abstraction แบบบางสำหรับงาน SIMD ด้าน arithmetic และ bit operation
  • สร้างแพ็กเกจภายในที่มี implementation ของ Plan9 แยกตามสถาปัตยกรรม และตั้งค่าผ่านฟังก์ชันเริ่มต้น

ตัวอย่าง SIMD

  • อธิบายวิธีใช้ SIMD ผ่านตัวอย่างฟังก์ชัน x86 SIMD Plan9
  • แสดงวิธีตรวจสอบการรองรับ SSE และการทำงานบวก float32 ผ่านไฟล์ Supported_amd64.s และ AddFloat32_amd64.s

ประสิทธิภาพและอนาคต

  • จากกราฟที่แสดงความต่างด้านประสิทธิภาพระหว่าง implementation แบบซอฟต์แวร์ของ Go กับ implementation แบบ Plan9 SIMD พบว่าความเร็วเพิ่มขึ้นประมาณ 200-450%
  • หวังว่าบันทึกนี้จะเป็นแรงบันดาลใจให้กับโปรเจกต์ที่ใช้ Plan9 และ SIMD

# สรุปโดย GN⁺

  • บทความนี้แนะนำวิธีเพิ่มประสิทธิภาพสูงสุดด้วยการใช้ประโยชน์จาก concurrency และ parallelism ของ Go
  • อธิบายวิธีทำการคำนวณแบบขนานในระดับฮาร์ดแวร์ด้วยภาษาแอสเซมบลี Plan9 และคำสั่ง SIMD
  • บทความนี้นำเสนอความเป็นไปได้ในการใช้ Plan9 และ SIMD ให้กับนักพัฒนา Go และอาจมีประโยชน์ต่อการสำรวจแนวทางใหม่ ๆ เพื่อเพิ่มประสิทธิภาพ
  • โปรเจกต์ที่มีความสามารถคล้ายกันซึ่งแนะนำ ได้แก่ ไลบรารีรองรับ SIMD ของ Rust หรือไลบรารีที่เกี่ยวข้องกับ SIMD ของ C++

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

 
GN⁺ 2024-10-19
ความคิดเห็นบน Hacker News
  • คำอธิบายเกี่ยวกับ "NOSPLIT": เป็นไวยากรณ์เฉพาะในแอสเซมบลีของ Go ที่ใช้อธิบายขนาดเฟรมและขนาดอาร์กิวเมนต์

    • ขนาดเฟรมและขนาดอาร์กิวเมนต์ถูกคั่นด้วย '-' ซึ่งไม่ใช่การลบทางคณิตศาสตร์
    • เครื่องมือ "go vet" จะตรวจสอบว่าขนาดอาร์กิวเมนต์ถูกต้องหรือไม่
  • ความเห็นเกี่ยวกับการตีความของ LLM (โมเดลภาษาขนาดใหญ่): อาจมีความเข้าใจผิดในการตีความโค้ด

    • มีความเห็นว่าหากผู้เขียนยอมรับอย่างตรงไปตรงมา ก็จะช่วยให้เกิดการเรียนรู้ได้
  • การกล่าวถึง "Plan9" ซึ่งเป็นภาษาแอสเซมบลีภายในของ Go: Go ใช้ภาษาแอสเซมบลีของตัวเอง

    • บน amd64, int มีขนาด 64 บิต และหากใช้ int32 จะถูกจัดแนวตาม word ในรายการอาร์กิวเมนต์
    • NOSPLIT ถูกกำหนดไว้ใน textflag.h และมีผลใช้ได้เฉพาะในรันไทม์
  • คำอธิบายของ Rob Pike เกี่ยวกับการออกแบบแอสเซมบลีของ Go: เพื่อสร้างภาษาแอสเซมบลีแบบร่วมกันที่ช่วยให้สื่อสารกับเครื่องได้โดยไม่ต้องเรียนรู้ไวยากรณ์ใหม่

    • สามารถสร้างแอสเซมเบลอร์โดยอัตโนมัติได้จากการป้อนเอกสารอธิบายสถาปัตยกรรมใหม่
  • ความเห็นเกี่ยวกับการใช้ฟังก์ชันสำหรับการคำนวณ SIMD: ควรมีฟังก์ชันที่สามารถทำ SIMD กับ slice ได้

    • เวลาบวกสอง slice เข้าด้วยกัน ควรใช้ SIMD เพื่อประมวลผลแบบขนานแทนการใช้ลูป for
  • ปรัชญาการออกแบบคอมไพเลอร์ของ Go: มุ่งไปที่คอมไพเลอร์ที่เรียบง่ายและรวดเร็วมากกว่าคอมไพเลอร์ที่ซับซ้อน

    • การรองรับ x64 พื้นฐานรวม SSE และ SSE2 ไว้แล้ว และให้ความสำคัญกับความเรียบง่ายมากกว่าประสิทธิภาพ
  • ความเห็นเกี่ยวกับการใช้ GPU สำหรับการคำนวณ SIMD: GPU อาจเหมาะกับ SIMD มากกว่า เพราะเด่นด้านการประมวลผลแบบขนานและการคำนวณเมทริกซ์

    • อย่างไรก็ตาม ใน Go อาจไม่เหมาะนักเนื่องจากยังขาดแพ็กเกจ GPU และชุมชนที่รองรับ