JIT Trace ในโลกจริงจาก CPython Core Dev Sprint
(antocuni.eu)นี่คือสรุปเชิงลึกเกี่ยวกับความท้าทายทางเทคนิคที่คอมไพเลอร์ JIT (Just-In-Time) แบบติดตามตัวใหม่ของ CPython กำลังเผชิญอยู่
ตัวขัดขวางการติดตาม (Trace Blockers)
JIT แบบติดตามจะระบุ เส้นทางโค้ดที่ถูกรันบ่อยระหว่างการทำงานของโปรแกรม ("hot path") แล้วบันทึก micro-operations ของเส้นทางนั้นเพื่อสร้าง machine code ที่ผ่านการปรับให้เหมาะสม อย่างไรก็ตาม เมื่อ JIT เจอโค้ดที่มันมองเข้าไปภายในไม่ได้ หรือก็คือ "ตัวขัดขวางการติดตาม" กระบวนการนี้จะหยุดชะงัก สำหรับ CPython ตัวอย่างที่พบได้บ่อยคือการเรียกใช้ฟังก์ชันส่วนขยายที่เขียนด้วย C
- คำอธิบายเชิงเทคนิค: ในบล็อกมีการยกฟังก์ชัน Python ล้วนที่ใช้คำนวณค่า π เป็นตัวอย่าง JIT ของ PyPy สามารถปรับแต่งลูปคำนวณตัวเลขนี้ได้อย่างมีประสิทธิภาพมาก และให้ประสิทธิภาพเร็วกกว่า CPython ถึง 42 เท่า แต่ถ้าเพิ่มการเรียกฟังก์ชัน C เพียงตัวเดียวที่ JIT ติดตามไม่ได้ (
hic_sunt_leones()) เข้าไปในลูป ประสิทธิภาพของ PyPy จะตกฮวบจนเหลือเร็วกว่า CPython เพียง 1.8 เท่าเท่านั้น “ตัวขัดขวางการติดตาม” เพียงจุดเดียวนี้ทำให้ความสามารถในการปรับแต่งของ JIT แทบหมดประสิทธิภาพ นั่นเป็นเพราะ JIT ไม่รู้การทำงานภายในของฟังก์ชัน C จึงไม่สามารถปรับลูปทั้งก้อนเป็นหน่วยเดียวได้ และต้องแยกจัดการโค้ดก่อนกับหลังการเรียกฟังก์ชัน C
การควบคุมการไหลของโปรแกรมที่ขับเคลื่อนด้วยข้อมูล (Data-Driven Control Flow)
ปัญหานี้เกิดขึ้นเมื่อ การไหลของโปรแกรมเปลี่ยนแปลงอย่างมากตามข้อมูลนำเข้า JIT แบบติดตามทำงานได้ดีที่สุดภายใต้สมมติฐานว่ามี "hot path" ที่สม่ำเสมออยู่ แต่ถ้าเส้นทางการทำงานเปลี่ยนไปเรื่อย ๆ ตามข้อมูล สมมติฐานนี้ก็จะพังลง
- คำอธิบายเชิงเทคนิค: ในบล็อกยกตัวอย่างฟังก์ชันที่รับอาร์กิวเมนต์ 9 ตัว โดยแต่ละตัวอาจเป็น
Noneหรือเป็นตัวเลขก็ได้ ภายในฟังก์ชันมีเงื่อนไขในรูปแบบif <var> is None: ...เรียงต่อกัน ในกรณีนี้ เส้นทางโค้ดที่ถูกรันจะเปลี่ยนไปทุกครั้งตามชุดค่าผสมของค่าNoneที่ส่งเข้ามา ดังนั้น JIT จึงต้องเผชิญกับปัญหา "จำนวน trace แบบทวีคูณ (exponential number of traces)" กล่าวคือ JIT จะพยายามสร้างโค้ดที่ปรับแต่งแยกต่างหากสำหรับทุกชุดค่าผสมที่เป็นไปได้ของอาร์กิวเมนต์Noneซึ่งก่อให้เกิด overhead มหาศาล และสุดท้ายอาจช้ากว่า CPython ที่ไม่ใช้ JIT อย่างมากเสียอีก
สรุปคือ โพสต์บล็อกนี้เน้นย้ำว่าเพื่อให้ JIT แบบติดตามตัวใหม่ของ CPython ประสบความสำเร็จ มันจำเป็นต้องแก้ปัญหา "ตัวขัดขวางการติดตาม" และ "การควบคุมการไหลของโปรแกรมที่ขับเคลื่อนด้วยข้อมูล" เหล่านี้ให้ได้ ซึ่งชี้ให้เห็นว่านี่อาจไม่ใช่แค่ปัญหาเชิงการใช้งานเท่านั้น แต่ยังอาจเป็นข้อจำกัดพื้นฐานของเทคโนโลยี JIT แบบติดตามเองด้วย
ยังไม่มีความคิดเห็น