- CCC (Claude’s C Compiler) ที่ Claude Opus 4.6 ของ Anthropic เขียนขึ้นทั้งหมดถูกเผยแพร่พร้อมคำกล่าวว่าสามารถคอมไพล์ลินุกซ์เคอร์เนลได้
- เป็น คอมไพเลอร์แบบสแตนด์อโลนที่เขียนด้วย Rust โดยพัฒนาทุกองค์ประกอบเองตั้งแต่ฟรอนต์เอนด์ถึงลิงเกอร์ แต่ ประสิทธิภาพและคุณภาพของการปรับแต่งให้เหมาะสมยังด้อยกว่า GCC มาก
- ในเบนช์มาร์กกับ SQLite และ Linux kernel นั้น CCC คอมไพล์ไฟล์ C ทั้งหมดได้โดยไม่มีข้อผิดพลาด แต่ การบิลด์ล้มเหลวในขั้นตอนลิงก์จากข้อผิดพลาดอ้างอิง 4 หมื่นกว่ารายการ
- ประสิทธิภาพการรันของ SQLite ช้าที่สุดมากถึง 158,000 เท่า, ขนาดไบนารี ใหญ่กว่า 3 เท่า, และ ออปชันปรับแต่งอย่าง
-O2 ใช้งานไม่ได้ผล
- การที่ AI สร้างคอมไพเลอร์ C แบบสมบูรณ์ได้ถือว่ามีความหมายในเชิงเทคนิค แต่ ด้านประสิทธิภาพและความเข้ากันได้สำหรับการใช้งานจริงยังไม่ถึงระดับที่ใช้ได้
ภาพรวมและโครงสร้างของ CCC
- CCC คือ คอมไพเลอร์ C ที่ AI เขียนขึ้นทั้งหมด โดย Anthropic ใช้ Claude สร้าง และรองรับ x86-64, i686, AArch64, RISC-V 64
- เขียนด้วย Rust พร้อม IR แบบอิง SSA, ตัวปรับแต่ง, ตัวสร้างโค้ด, แอสเซมเบลอร์, ลิงเกอร์, และการสร้างข้อมูลดีบัก DWARF
- มีการอธิบายแยกบทบาทของ คอมไพเลอร์·แอสเซมเบลอร์·ลิงเกอร์ โดยระบุว่าลิงเกอร์ซับซ้อนที่สุดและมีโอกาสเกิดข้อผิดพลาดสูงสุด
- เนื่องจากลินุกซ์เคอร์เนลใช้ส่วนขยายของ GCC และสคริปต์ลิงเกอร์ที่ซับซ้อน จึงไม่เหมาะเป็นเป้าหมายทดสอบเริ่มต้น และเลือก SQLite เป็นเบนช์มาร์กหลักแทน
สภาพแวดล้อมและวิธีการทดสอบ
- เปรียบเทียบ GCC 14.2.0 กับ CCC ภายใต้เงื่อนไขเดียวกันบน VM ที่ใช้ Debian จำนวน 2 เครื่อง (6 vCPU, RAM 16GB)
- รายการเปรียบเทียบ: เวลาคอมไพล์, ขนาดไบนารี, ความเร็วในการรัน, การใช้หน่วยความจำ, เสถียรภาพ
- CCC ใช้ฟีเจอร์ gcc_m16 เพื่อมอบหมายเฉพาะโค้ดบูต 16 บิตให้ GCC ส่วนที่เหลือให้ CCC จัดการ
- เบนช์มาร์ก SQLite ออกแบบให้เน้น CPU โดยรันการทำงาน SQL 42 รายการใน 10 ขั้นตอน
สรุปผลลัพธ์หลัก
- Linux kernel 6.9: CCC คอมไพล์ไฟล์ C ทั้ง 2,844 ไฟล์ได้ครบ แต่ ล้มเหลวในขั้นตอนลิงก์เพราะมีข้อผิดพลาด
undefined reference 40,784 รายการ
- สาเหตุของข้อผิดพลาด: การ relocation และการสร้างสัญลักษณ์ของเซกชัน
__jump_table, __ksymtab ไม่ถูกต้อง
- การคอมไพล์ SQLite: CCC ช้ากว่า GCC 1.3 เท่า, ขนาดไบนารี 2.7~3 เท่า, ใช้หน่วยความจำ 5.9 เท่า
- ประสิทธิภาพการรัน SQLite: ช้ากว่า GCC -O0 737 เท่า และช้ากว่า -O2 1,242 เท่า
- คิวรีแบบง่ายช้ากว่า 1~7 เท่า ส่วนคิวรีแบบ nested loop ช้าที่สุดถึง 158,000 เท่า
- ผ่าน การทดสอบ crash ทั้ง 5 แบบ แสดงว่ามีความถูกต้องเชิงฟังก์ชัน
สาเหตุของประสิทธิภาพที่ลดลง
- มี register spilling มากเกินไป: ตัวแปรภายในส่วนใหญ่ถูกเก็บไว้บนสแตก ทำให้เกิดการเข้าถึงหน่วยความจำมากเกินจำเป็น
- ในฟังก์ชัน
sqlite3VdbeExec มีตัวแปรมากกว่า 100 ตัวถูกจัดการผ่านสแตก ทำให้โค้ดยาวขึ้น 3 เท่า
- ออปชันปรับแต่งใช้ไม่ได้ผล: ผลลัพธ์ของ
-O0 และ -O2 เหมือนกันทั้งหมด โดยมี SSA pass 15 รายการที่ทำงานเหมือนกันในทุกระดับ
- frame pointer เสียหาย ทำให้ดีบักด้วย GDB ไม่ได้
- ขนาดโค้ดพองตัว: ไบนารีของ SQLite มีขนาด 4.27MB หรือมากกว่า GCC 2.78 เท่า ทำให้ instruction cache miss เพิ่มขึ้น
- ไม่มีการสร้าง symbol table: ไม่มีสัญลักษณ์ของฟังก์ชันภายใน จึงทำ profiling ไม่ได้
จุดแข็งและข้อจำกัดของ CCC
- จุดแข็ง
- คอมไพล์ไฟล์ C ทั้งหมดของลินุกซ์เคอร์เนลได้โดยไม่มีข้อผิดพลาด
- ผลลัพธ์ของ SQLite มี ความถูกต้องและเสถียรภาพ, ไม่มี segmentation fault
- รองรับ command-line interface ที่เข้ากันได้กับ GCC
- ข้อจำกัด
- ความเร็วในการรันลดลงอย่างรุนแรง (สูงสุด 158,000 เท่า)
- ลิงเกอร์ไม่เข้ากัน จึงทำให้บิลด์เคอร์เนลไม่สำเร็จ
- ขนาดไบนารีและการใช้หน่วยความจำสูงเกินไป
- ขาดการปรับแต่งและข้อมูลดีบัก, ออปชัน
-O ใช้ไม่ได้ผล
- ความเร็วในการคอมไพล์ ก็ช้ากว่า GCC 25%
ปัญหา “Hello World”
- หลังเผยแพร่ไม่นาน ก็เกิดประเด็น “Hello world does not compile”
- ล้มเหลวในขั้นตอน preprocessing เพราะหา
stddef.h, stdarg.h ไม่พบ
- บน GitHub มีปฏิกิริยามากกว่า 288 รายการและคอมเมนต์ราว 200 ข้อความ จนกลายเป็นประเด็นพูดถึง
- ผู้ใช้บางส่วนประเมินว่า “ดูเหมือนงานคอมไพเลอร์ระดับนักศึกษาปริญญาตรี”
บทสรุป
- CCC คือ กรณีพิสูจน์ว่า AI สามารถสร้างคอมไพเลอร์ C ที่สมบูรณ์ได้
- สามารถจัดการไฟล์ C ทั้งหมดของลินุกซ์เคอร์เนลได้โดยไม่มีข้อผิดพลาด และรัน SQLite ได้อย่างถูกต้องเชิงฟังก์ชัน
- อย่างไรก็ตาม ยังไม่เหมาะกับการใช้งานจริง
- ประสิทธิภาพการรันต่ำมาก และฟังก์ชันด้านลิงเกอร์ การปรับแต่ง และการดีบักยังไม่สมบูรณ์
- ในฐานะความสำเร็จเชิงวิจัยถือว่ามีความหมาย แต่สำหรับคอมไพเลอร์ที่ใช้ในงานจริง เครื่องมือเดิมอย่าง GCC·Clang ยังจำเป็นอยู่
5 ความคิดเห็น
ที่แท้ต้นตอของมีม
Hello world does not compileก็อยู่นี่นี่เอง 555ตอนแรกก็บรรยากาศคล้าย ๆ โกะเลยนะ
ถ้าสั่งให้มันวนลูปแก้ไปเรื่อย ๆ สักวันหนึ่งมันก็น่าจะได้คอมไพเลอร์ที่ยอดเยี่ยมกว่านี้ออกมาไม่ใช่หรือ
คงต้องมองว่ามันมีความหมายในแง่ที่ไปถึงระดับงานของนักศึกษาปริญญาตรีได้แล้ว..
ความเห็นจาก Hacker News
ข้อถกเถียงครั้งนี้เป็นตัวอย่างที่ชัดเจนของมุมมองทั้งฝ่ายสนับสนุนและคัดค้านต่อ LLM coding agent
ฝ่ายสนับสนุนบอกว่า “น่าทึ่งมากที่สร้างคอมไพเลอร์ที่ใช้งานได้ภายในไม่กี่ชั่วโมง” ส่วนฝ่ายคัดค้านบอกว่า “ถ้าใช้งานจริงไม่ได้ก็ไม่มีความหมาย”
ยิ่งโค้ดเบสซับซ้อนมากเท่าไร เอเจนต์ก็ยิ่งอ่อนลง และหลายคนก็เริ่มกังขากับคำพูดแบบวนซ้ำว่า “รุ่นถัดไปจะแก้ได้เอง”
Anthropic เคยบอกว่าคอมไพล์ Linux kernel ได้ แต่ในความเป็นจริงล้มเหลว และเรื่องนี้ก็สะท้อนให้เห็น ช่องว่างระหว่างความคาดหวังที่เกินจริงต่อ AI กับความเป็นจริง
การผ่านการทดสอบและให้ผลลัพธ์ที่ดูเหมือนถูกต้องภายนอก กับการที่โค้ดนั้นมี คุณภาพที่ดูแลรักษาได้จริง เป็นคนละเรื่องกันโดยสิ้นเชิง
ตอนแรกบอกว่า “เขียนได้แค่ฟังก์ชันเล็ก ๆ” ต่อมาก็ “คอมไพล์ Linux ไม่ได้” แล้วก็ “ยังไม่ถึงระดับ GCC” เกณฑ์ถูกเลื่อนตลอดเวลา
แต่ถ้ามองจากความเร็วในการพัฒนา ก็รู้สึกว่าแค่มีวิศวกรคอมไพเลอร์สักไม่กี่คนเข้ามาช่วย ก็น่าจะไล่ตามได้เร็ว
เพราะอย่างนั้นจึงยังน่าสงสัยว่า LLM จะสามารถแก้ปัญหาใหม่อย่างแท้จริงได้หรือไม่
Anthropic เขียนในบล็อกว่า Linux kernel บูตได้บน x86 ด้วย แต่ดูเหมือนว่า สำเร็จจริงแค่บน RISC-V
ในโพสต์ทางการบอกว่าทำได้ทั้ง x86/ARM/RISC-V
แต่ในเอกสารของ repoมีแค่การทดสอบบน RISC-V
ตัวเลข ประสิทธิภาพที่ตกลง ของ C ที่ไม่ผ่านการ optimize น่าสนใจมาก
ในการ build SQLite3 นั้น CCC ช้ากว่า 12 เท่า และเวอร์ชันที่ optimize แล้วช้ากว่า 20 เท่า
นี่แสดงให้เห็นว่า GCC สร้าง ผลลัพธ์ด้าน optimization ได้มากขนาดไหน
แต่ถ้าคอมไพเลอร์มีการสลับ register มากเกินไป ความเชื่อมโยงนั้นก็หายไป และจะให้ความรู้สึกเหมือน Python
CCC ช้ากว่าแม้แต่
-O0ซึ่งก็น่าแปลกใจการที่ CCC คอมไพล์ไฟล์ C ทั้งหมดของ kernel ได้โดยไม่ error ไม่ได้แปลว่าได้ ผลลัพธ์ที่ถูกต้องตามปกติ
แค่ผ่านการทดสอบของ SQLite ยังไม่เพียงพอ
/dev/nullก็ไม่มี error เหมือนกันconstและยังปล่อยให้ type redefinition หรือการแปลงชนิดที่ผิดผ่านไปได้กล่าวคือ เพื่อให้บรรลุเป้าหมาย “ผ่านการทดสอบ” มันจึงใช้ทางลัดด้วยการ คอมไพล์โค้ดที่ไม่ถูกต้องให้ผ่าน
มีบางบทความบอกว่า “คอมไพเลอร์เป็นขั้นตอนที่ง่ายที่สุด” แต่จริง ๆ แล้ว linker คือส่วนที่ซับซ้อนที่สุด
การเข้ารหัสคำสั่งนับพันแบบของ x86-64 หรือรายละเอียด layout ของ ELF เป็นสิ่งที่ AI รับมือได้ยาก
อีกทั้งการคำนวณแบบ “รอบเดียวช้ากว่า 4 เท่า → ถ้าทำ 1 พันล้านรอบจะช้ากว่า 158,000 เท่า” ก็ไม่สมเหตุสมผล
แม้จะยังขาดคำสั่งอีกมาก แต่ก็อยู่ในระดับที่แค่เติมตารางข้อมูลเพิ่มก็ใช้ได้
น่าทึ่งที่ความคาดหวังของมนุษย์เปลี่ยนเร็วมาก
ถ้าย้อนกลับไปเมื่อ 5 ปีก่อน คำพูดว่า “AI สร้างคอมไพเลอร์ C จากพรอมต์ภาษาอังกฤษ” คงเป็น มุกที่เหลวไหลสิ้นดี
ไม่ค่อยเข้าใจความเหยียดหยันเกินเหตุใน HN
การสร้างคอมไพเลอร์ C สำหรับสามสถาปัตยกรรมเป็นเรื่องยากแม้แต่สำหรับมนุษย์ และถ้าทำได้ถึงระดับที่ผ่าน SQLite ก็ถือว่าเป็น ผลงานระดับโปรเจกต์วันหยุดสุดสัปดาห์ ที่น่าทึ่งแล้ว
บริษัทส่วนใหญ่ในความเป็นจริงไม่ได้ต้องการคอมไพเลอร์สมรรถนะสูง แต่ต้องการ โค้ดกาวสำหรับ business logic มากกว่า
ปัญหาไม่ได้อยู่ที่เทคโนโลยี แต่อยู่ที่ ท่าทีของคนที่ใช้งานมัน
ประเด็นสำคัญคือ ประสิทธิภาพที่ช้ากว่า 158,000 เท่า ใน SQLite
การ parsing เป็นปัญหาที่ง่าย ส่วนที่ยากจริงคือ ขั้น register allocation และ optimization
การเอาไปเทียบกับ GCC อาจไม่มีความหมายมากนัก แต่แค่ LLM สร้างคอมไพเลอร์แบบนี้ได้ก็น่าทึ่งแล้ว
เป้าหมายต่อไปคือทำให้ช่องว่างกับ GCC ลดจาก 158,000 เท่า เหลือราว 100 เท่า
ถ้าแต่ละรอบช้ากว่า 12 เท่า โดยรวมก็ควรช้ากว่า 12 เท่าเช่นกัน ดังนั้น 158,000 เท่าดูเหมือน ความผิดพลาดหรือความเข้าใจผิด
และก็ยังขาดการตรวจสอบว่าการทดสอบ SQLite รันได้อย่างถูกต้องจริงหรือไม่
ถึงอย่างนั้นประสิทธิภาพที่ต่ำขนาดนี้ก็ยังชวนสงสัย
ลองดูบทความ C ไม่ใช่ภาษาที่ parse ได้อย่างสมบูรณ์
อย่างที่มีคนชี้ว่า “ถ้ารอบเดียวช้ากว่า 8 เท่า ต่อให้ทำ 1 พันล้านครั้งก็ยังช้าแค่ 8 เท่า”
ตัวเลข 158,000 เท่าจึง ไม่สมเหตุสมผลในเชิงตรรกะ
อาจเป็นไปได้ว่า register spilling ไปกดทับ L3 cache หรือมีบั๊กที่ทำให้ไปรันโค้ดที่ไม่จำเป็น
การสร้างคอมไพเลอร์ C เป็นเรื่องยากแม้สำหรับมนุษย์
แต่ก็ยากจะมองว่านี่เป็น หลักฐานของความฉลาดของ LLM
มันเป็นปัญหาที่มีการรู้จักกันดีอยู่แล้ว และมี implementation กับเอกสารจำนวนมากอยู่ในข้อมูลฝึก
กล่าวอีกอย่างคือ LLM ไม่ได้สร้างสถาปัตยกรรมใหม่ แต่เป็นเพียงการ นำแพตเทิร์นเดิมมาประกอบใหม่
ถึงอย่างนั้นเครื่องมือแบบนี้ก็ยังมีประโยชน์อยู่ดี และ
สิ่งที่จะน่าประทับใจจริง ๆ ไม่ใช่การลอกเลียน OSS เดิม แต่คือการมีโมเดลที่ เสนอแนวทางใหม่ ได้