%การใช้งาน CPU เป็นเรื่องหลอกตา
(brendanlong.com)- โดยทั่วไปมักใช้ % การใช้งาน CPU จากเครื่องมือติดตามอย่าง
topเพื่อตัดสินขีดจำกัดด้านประสิทธิภาพของเซิร์ฟเวอร์ แต่ในความเป็นจริง ตัวชี้วัดนี้ ไม่ได้สะท้อนประสิทธิภาพแบบเชิงเส้น - ผลการทดสอบด้วย stress-ng บนเครื่อง Ryzen 9 5900X พบว่า เมื่อ การใช้งานอยู่ที่ 50% ภาระงานจริงกลับอยู่ที่ 60~100% ซึ่งแตกต่างจากตัวเลขที่รายงานอย่างมาก
- สาเหตุหลักคือ Hyper-Threading และ Turbo Boost ซึ่งทำให้การแชร์ทรัพยากรระหว่างคอร์เชิงตรรกะและการเปลี่ยนแปลงความถี่สัญญาณนาฬิกาบิดเบือนตัวชี้วัดนี้
- ดังนั้น แทนที่จะดูเพียงการใช้งาน CPU ควรใช้ เบนช์มาร์กของปริมาณงานที่ประมวลผลได้จริง และเปรียบเทียบกับ throughput ปัจจุบัน ซึ่งแม่นยำกว่า
- หากตีความการใช้งาน CPU แบบเชิงเส้น จะทำให้เกิด ความคลาดเคลื่อนอย่างมากในการประเมินประสิทธิภาพ ดังนั้นการวางแผนระบบจึงควรใช้ แนวทางที่อิงเบนช์มาร์ก
ความไม่สอดคล้องกันระหว่างตัวเลขการใช้งาน CPU ของเซิร์ฟเวอร์กับ throughput จริง
- ระหว่างการดูแลเซิร์ฟเวอร์ หลายคนต้องการรู้ว่าระบบเข้าใกล้การใช้งานสูงสุดหรือยัง
- โดยทั่วไปมักอ้างอิงค่าที่สูงที่สุดในบรรดาการใช้งานเครือข่าย หน่วยความจำ และ CPU ผ่านเครื่องมือติดตามอย่าง
top - แต่ในทางปฏิบัติ มีปัญหาที่ตัวเลขการใช้งาน CPU กับปริมาณงานที่ประมวลผลได้จริงไม่ได้เพิ่มขึ้นแบบเชิงเส้น
สภาพแวดล้อมและวิธีการทดสอบ
- การทดลองบน Ubuntu เดสก์ท็อป + Ryzen 9 5900X (12 คอร์/24 เธรด)
- เปิดใช้งาน Precision Boost Overdrive (Turbo)
- ใช้ stress-ng จำลองโหลดหลายรูปแบบ (1~24 worker, การใช้งาน 1~100%)
- ตัวชี้วัดที่วัด: การใช้งาน CPU ที่ระบบรายงาน และปริมาณการคำนวณจริง (Bogo ops)
สรุปผลลัพธ์
- โหลด CPU ทั่วไป: ที่การใช้งาน 50% ได้ throughput จริง 60~65%
- การคำนวณจำนวนเต็ม 64 บิต: ที่การใช้งาน 50% ได้ throughput 65~85%
- การคำนวณเมทริกซ์ (Matrix math): ที่การใช้งาน 50% ได้ throughput 80~100%
- ในความเป็นจริง แม้ worker เพิ่มเติมจะไม่ช่วยเพิ่มประสิทธิภาพ การใช้งาน CPU ก็ยังสูงขึ้น
การวิเคราะห์สาเหตุ
-
Hyper-Threading
- โครงสร้างประกอบด้วย 12 คอร์จริง + 12 คอร์เชิงตรรกะ
- เมื่อมี worker ไม่เกิน 12 ตัว จะถูกจัดลงคอร์จริงได้อย่างเหมาะสม แต่เมื่อเกินจากนั้นจะเกิด การแชร์คอร์เชิงตรรกะ ทำให้ประสิทธิภาพลดลง
- โดยเฉพาะใน การคำนวณ SIMD (การคำนวณเมทริกซ์) จะไม่มีทรัพยากรที่แชร์แล้วช่วยเพิ่มประสิทธิภาพได้
-
Turbo Boost
- เมื่อโหลดต่ำ ความถี่อยู่ที่ 4.9GHz → เมื่อโหลดเต็มลดลงเหลือ 4.3GHz ทำให้ ความถี่ลดลง 15%
- ทำให้เกิดความบิดเบือนในสูตรคำนวณการใช้งาน CPU (= busy cycles / total cycles)
- เมื่อส่วนหาร (จำนวน cycle ทั้งหมด) ลดลง อัตราการใช้งานที่เพิ่มขึ้นจึงถูกประเมินสูงเกินจริงเมื่อเทียบกับปริมาณงานจริง
ข้อสังเกตสำคัญ
- การใช้งาน CPU ไม่ใช่ตัวชี้วัดประสิทธิภาพแบบสัมบูรณ์
- เมื่อต้องประเมินขนาดระบบและคาดการณ์ประสิทธิภาพของเซิร์ฟเวอร์:
- 1. วัด throughput สูงสุดด้วยเบนช์มาร์ก
- 2. ติดตาม throughput แบบเรียลไทม์
- 3. เปรียบเทียบสองค่านี้เพื่อ ตัดสินว่าระบบเข้าใกล้ขีดจำกัดประสิทธิภาพหรือไม่
- เนื่องจาก สถาปัตยกรรม CPU (AMD vs Intel), ประสิทธิภาพของ Hyper-Threading และรูปแบบการทำงานของ Turbo แตกต่างกันมาก จึงจำเป็นต้องวิเคราะห์แยกตามโปรเซสเซอร์
บทสรุป
- การใช้งาน CPU เป็นเพียง สัดส่วนของ cycle ที่กำลังทำงานอยู่ เท่านั้น ไม่ได้สะท้อนสมรรถนะการประมวลผลจริงอย่างแม่นยำ
- หากใช้งานได้อย่างมีประสิทธิภาพ ต่อให้แสดงว่า "ใช้งาน 50%" ก็อาจหมายถึง ถึงระดับ 80~100% ของประสิทธิภาพสูงสุดแล้ว
- ดังนั้น การติดตามประสิทธิภาพและการวางแผนระบบ ควรยึด throughput ของงานที่อิงเบนช์มาร์ก เป็นหลัก แทนการดูการใช้งาน CPU เพียงอย่างเดียว
3 ความคิดเห็น
ในสภาพแวดล้อมการตั้งค่า HPC จริง โดยพื้นฐานแล้วจะปิด Hyper-Threading และจัดคอนฟิกคลัสเตอร์ครับ
ความคิดเห็นจาก Hacker News
ผมไม่คิดว่า CPU utilization จะเป็นเรื่องโกหกในแง่ที่มันเป็นการวัดปริมาณที่นิยามไว้ค่อนข้างชัดเจน แต่พอคนพยายามเอามันไป extrapolate เพื่อสร้างโมเดลความจุ ก็มักเจอว่าความเป็นจริงไม่ตรงกับที่คาด
Hyperthreading (SMT) และ Turbo (clock scaling) เป็นเพียงบางส่วนของตัวแปรที่ทำให้เกิดความไม่เป็นเชิงเส้นเท่านั้น และยังมีทรัพยากรอย่าง memory bandwidth ที่แชร์กันระหว่างคอร์ ความจุของ interconnect และ processor cache ที่จะค่อย ๆ “หมด” ไปเมื่อโหลดเพิ่มขึ้น
ในฝั่งซอฟต์แวร์เองก็เช่นกัน ตัวอย่างอย่าง spinlock สามารถส่งผลต่อ utilization แบบไม่เป็นเชิงเส้นได้
metric CPU utilization ส่วนใหญ่มักเฉลี่ยค่าเป็นช่วงยาวระดับหลายวินาทีถึง 1 นาที แต่สิ่งที่สำคัญต่อประสิทธิภาพของเซิร์ฟเวอร์ที่ไวต่อ latency มักเกิดขึ้นในช่วงเพียงหลักสิบถึงหลักร้อยมิลลิวินาที
เพราะงั้น utilization ที่เป็นค่าเฉลี่ยหลายวินาทีจึงแยกไม่ออกระหว่างรูปแบบ burst กับรูปแบบที่เรียบสม่ำเสมอ
แต่แนวทางที่เสนอไว้ คือการ “benchmark ว่าเซิร์ฟเวอร์ทำงานได้มากแค่ไหนก่อนจะเกิด error หรือ latency ที่ยอมรับไม่ได้” ก็มีความไม่เสถียรในตัวเองเหมือนกัน
ตอนพยายามหาจุดที่เซิร์ฟเวอร์เริ่มไม่เสถียร ค่าที่วัดได้จะ noisy มาก และตามทฤษฎีคิว เมื่อเข้าใกล้จุดวิกฤต noise ทุกอย่างจะถูกขยายขึ้น
อีกทั้งตัว “ปริมาณงานที่เซิร์ฟเวอร์กำลังทำอยู่ตอนนี้” เองก็มักนิยามได้ไม่เสถียรอยู่แล้ว (เป็น RPS ไหม? แต่ละ request มีต้นทุนไม่เท่ากัน และ IPC ก็เปลี่ยนไปตามช่วงเวลา)
สุดท้ายแล้ว ช่วงความเชื่อมั่นที่ได้จากแนวทาง load test ก็ไม่ได้ต่างจากการสร้างโมเดลเชิงประจักษ์จาก metric utilization มากนัก โดยมีข้อสมมติสำคัญว่าต้องวัด utilization ได้อย่างถูกต้อง
ถ้าคุณใช้ perf หรือ ftrace เป็น คุณจะได้ metric ของโปรเซสเซอร์ที่ละเอียดมากในช่วงเวลาสั้น ๆ และเห็นสาเหตุต่าง ๆ ได้ตรง ๆ เช่น CPU stall จาก cache miss หรือ memory access, ผลกระทบจาก scheduler เป็นต้น
แต่คนส่วนใหญ่ ต่อให้ได้รับ metric อย่าง IPC หรือ cache hit rate มา ก็ไม่รู้ว่าจะเอาไปทำอะไรต่อ
สุดท้ายสิ่งที่คนส่วนใหญ่สนใจจริง ๆ ก็คือ latency กับ utilization
ถ้าพูดแบบหยาบ ๆ สำหรับ workload ส่วนใหญ่ latency จะยังไม่มีปัญหามากนักจนกว่า CPU utilization จะเกิน 80%
แต่เมื่อสูงกว่านั้น ก็จะเริ่มส่งผลรุนแรงต่อ latency ของ workload
ว่ามันกระทบ latency มากแค่ไหน ต้องวัดกับ workload ของตัวเองเท่านั้นถึงจะรู้
และความไวต่อ latency ก็ขึ้นอยู่กับองค์กรและเป้าหมาย บางครั้งการ optimize throughput อาจสำคัญกว่า
ถ้าคุณแคร์ทั้ง latency และ throughput ก็ต้องวัดทั้งคู่ แล้วตัดสินใจ trade-off ที่เหมาะสมด้วยตัวเอง
ผมคิดว่าประเด็นสำคัญอย่างหนึ่งคือแม้แต่นิยามของ “ปริมาณงาน” เองก็ยังสั่นคลอน
ตัวอย่างเช่น ต่างกันมากระหว่างบริการ public-facing ที่รับ request จากผู้ใช้จริง กับ workload สำหรับฝึก AI ที่ค่อย ๆ ประมวลผลข้อมูลที่สะสมไว้ใน backend
วิธีมองของผมคือ ในสภาพแวดล้อม CPU สมัยใหม่แบบ multicore + hyperthread ที่ burst เกิดขึ้นได้บ่อยอยู่แล้ว ถ้า CPU utilization อยู่ที่ 60% ก็ถือว่าเป็นเซิร์ฟเวอร์ที่ “โหลดสูง” แล้ว
ถ้าระหว่างวันมีช่วงเวลานานพอสมควรที่เกิน 60% ผมจะมองว่าควรแยกงานออกไป (โดยหลักหมายถึงบริการที่ตอบสนอง request ของผู้ใช้)
ในอดีต เกณฑ์แบบนี้ทำให้ต้องคิดเรื่อง cloud autoscaling บ่อยมาก
ทุกวันนี้เซิร์ฟเวอร์ระดับเกิน 100 คอร์ก็หาใช้ได้ในราคาราว 30,000 ดอลลาร์ ทำให้สถานการณ์ซับซ้อนขึ้นไปอีก
ถ้าเป็นตอนนี้ ผมจะเอนเอียงไปทาง hybrid คือ provision ฮาร์ดแวร์จริงให้เผื่อไว้พอสมควร แล้วค่อยขยายไปยังบริการคลาวด์ (หรือ internal cloud ที่ใช้ Kubernetes) ตามต้องการ
ช่วงแรก ๆ ของ StackOverflow ก็เคยรันทราฟฟิกมหาศาลได้อย่างมีประสิทธิภาพด้วย rack เฉพาะและ uplink 10Gbps และตอนนี้การทำแบบนั้นง่ายกว่าเดิมอีก
สรุปคือ ตามเกณฑ์ของผม ถ้า CPU load คงอยู่ที่ 65% นานเกิน 30 นาที ก็ถือว่าใช้งานได้เต็มประสิทธิภาพ 100% แล้ว และควรขยายระบบในเร็ววัน
ใน keynote ล่าสุดของงานประชุม IEEE Hot Interconnects ก็มีการพูดถึงกรณีการปรับ latency ของ Ultra Ethernet ด้วย
ถ้ามองเป็นช่วง 2 วินาทีหรือ 5 วินาทีอาจดูเรียบ แต่ถ้าซูมลงไปที่สเกล 100ms จะเห็นปรากฏการณ์ frame burst ชัดเจน
กล่าวคือ ถ้า measurement window ของการ profiling ไม่สอดคล้องกับ workload จริง ก็อาจตัดสินผิดแบบ false negative ได้ และนั่นจะยิ่งทำให้ปัญหาแย่ลง
เห็นด้วยกับประเด็นที่พูดมาอย่างยิ่ง
เพราะ CPU utilization ไม่ได้มีคุณสมบัติเป็นเชิงเส้น ค่า % เองจึงยิ่งห่างจากความเป็นจริง
กล่าวอีกแบบคือ สิ่งที่เป็น “เรื่องโกหก” คือ CPU utilization ที่วัดออกมาเป็นหน่วย %
ถ้า workload สองแบบต่างก็แสดง CPU usage 100% เท่ากัน แต่ฝั่งหนึ่งกินไฟมากกว่าอย่างชัดเจนและทำให้อุณหภูมิ CPU พุ่งสูงกว่า มันก็ทำให้สงสัยว่าในความเป็นจริง workload นั้นกำลังใช้ทรัพยากรระดับทรานซิสเตอร์มากกว่าหรือเปล่า
แม้ CPU utilization จะไม่ใช่มาตรวัดที่สมบูรณ์แบบ แต่มันก็มีประโยชน์ในทางปฏิบัติ
จากประสบการณ์งาน SRE แบบง่าย ๆ ผมเคยเอาค่า CPU utilization ไปประกอบกับทฤษฎีคิวสำหรับงานที่เป็น CPU-bound เพื่อประเมินขนาดเซิร์ฟเวอร์ก่อนอีเวนต์ใหญ่ และแม้จะใช้เกณฑ์ %CPU ที่เสนอแบบอนุรักษ์นิยมกว่าวิธี “ดั้งเดิม” ก็ตาม ผลลัพธ์ก็ยังคุ้มค่าด้านต้นทุนกว่ามาก
ประเด็นสำคัญคือ ต่อให้เป็นมาตรวัดที่ไม่แม่นยำนัก ถ้าใช้หน้างานได้จริงก็ควรลองใช้โดยไม่ต้องกังวลเกินไป
แต่เหตุผลที่ผมพยายามไม่ให้ CPU utilization ใน production เกิน 40% ก็เพื่อรักษา headroom ไว้เล็กน้อยสำหรับสถานการณ์หลายรูปแบบ
รู้สึกเสียดายที่ผู้เขียนยังขาดเหตุผลเชิงตรรกะว่าทำไมจึงควร “หลีกเลี่ยง utilization สูงตามทฤษฎีคิว”
ผมคิดว่าต่อให้เป็น metric ที่หลวม ๆ ถ้าใช้ได้เหมาะสมในภาคสนามก็เพียงพอแล้ว
ยกตัวอย่างเช่น ไม่ว่าจะใช้ค่าเฉลี่ย/ค่าสูงสุดของ percentile metric รายโฮสต์แบบตรง ๆ หรือคำนวณ percentile ตอน aggregate histogram ระดับโฮสต์ในขั้นสุดท้าย จากประสบการณ์จริงพบว่าการสลับระหว่างสองแบบนี้แทบไม่ทำให้การปฏิบัติการต่างกันอย่างมีนัยสำคัญ
มีบางคนที่กังวลมากเรื่องความถูกต้องทางคณิตศาสตร์แบบเป๊ะ ๆ แต่ในระบบจริงหลายครั้งมันไม่ได้ส่งผลมากนัก
40% นี่จริง ๆ ก็ถือว่าเป็น utilization ที่เผื่อเยอะพอสมควรแล้ว
ผมคิดว่าถ้าดู CPU% ควบคู่กับ loadavg ก็พอจะเข้าใจสถานะของระบบได้ดีทีเดียว
ถ้า loadavg สูงแต่ CPU% ต่ำ ก็อาจติดที่เครือข่ายหรือ I/O หรือกำลังรอ system call อยู่
ถ้าอย่างนั้นมองแต่ CPU% อย่างเดียวก็อาจพลาดจุดที่ระบบกำลังลำบากอยู่ได้
รู้สึกเหมือนเคยได้ยินเรื่องเดียวกันนี้มาก่อน
สิ่งที่ผู้เขียนพูดถึงเป็นเนื้อหาที่ตำราทฤษฎีคิวพูดซ้ำมาหลายสิบปีแล้ว แต่ผู้เขียนกลับเขียนเหมือนเพิ่งค้นพบตอนนี้ ซึ่งก็น่าแปลกดี
ทำให้นึกถึงบทความของ Brendan Gregg เรื่อง "CPU Utilization is Wrong"
ใจความสำคัญของบล็อกนี้คือ CPU utilization วัดแค่ “สถานะ” ที่ CPU กำลังยุ่งอยู่ และถึงขั้นนับว่า busy แม้ตอนที่ CPU กำลังรออยู่
ส่วน IPC คือมาตรวัดที่ช่วยมองเห็นปริมาณงานที่มีประโยชน์จริงซึ่งซ่อนอยู่ภายในสถานะ busy นั้น
ถ้ามี Brendan อีกคนอยู่ ก็หวังว่าจะมาอธิบายได้
ผมไม่คิดว่าควรนับประสิทธิภาพจาก hyperthread ว่าเพิ่มเป็นสองเท่า
ในโลกจริง ต่อให้ใช้ hyperthread ได้ดี ก็มักได้ประสิทธิภาพเพิ่มแค่ราว 15~30% เท่านั้น ขณะที่ latency อาจเพิ่มเป็นสองเท่าได้
และเมื่อ core utilization สูงขึ้น ก็ต้องคำนึงถึงการลดลงของ clock ด้วย เพราะในความเป็นจริงมันไม่เป็นเชิงเส้นเสมอ
ต่อให้ใช้แค่ข้อมูลที่ OS ให้มา ถ้าเอาผลของ hyperthread และการลด clock มาคำนวณด้วย ก็จะประเมิน utilization ได้แม่นขึ้นมาก
ไปไกลกว่านั้น การทำโมเดลผลกระทบจากข้อจำกัดของ cache/memory bandwidth หรือ pipeline stall ที่ทำให้ประสิทธิภาพลดลง ก็ไม่ใช่เรื่องยากมากนักในมุมมองผม
ปัจจัยที่ทำให้เรื่องนี้ซับซ้อนขึ้นคือประสิทธิภาพของ hyperthread ต่างกันสุดขั้วตามสถาปัตยกรรม CPU และแต่ละ workload
ตัวอย่างเช่น การใช้งานของ AMD (โดยเฉพาะ Zen รุ่นใหม่ ๆ) มักให้ประสิทธิภาพที่เป็นอิสระกว่า Intel มาก (ถ้าสมมติว่าไม่มีคอขวดด้าน memory bandwidth)
ถ้าเป็นแอปพลิเคชันแบบ memory-bound ก็มักจะเห็น scaling จาก hyperthread ได้ดีกว่า
โปรเจกต์ renderer ที่ผมเคยดูแลก่อนหน้านี้เป็น memory-bound ทำให้ได้ประสิทธิภาพเพิ่มถึง 60~70% จาก hyperthread เพียงอย่างเดียว
เมื่อก่อนผมเคยรัน benchmark ง่าย ๆ ด้วย POV-Ray บน i7-3770K (4C/8T)
จาก 1 เธรดไป 2 เธรดได้สองเท่าพอดี จาก 2 ไป 4 ก็ยังได้สองเท่า แต่จาก 4 ไป 8 เพิ่มขึ้นแค่ 15% เอง
ถ้าเป็น benchmark แปลก ๆ ที่ตั้งใจให้เกิด cache miss ซ้ำ ๆ อาจดึงประสิทธิภาพจาก SMT ได้เกือบสองเท่าก็ได้ แต่ก็ไม่แน่ใจว่ามีความสมจริงแค่ไหน
ปล. กำลังคิดว่าจะกลับไปรันเทสต์ POV-Ray อีกครั้ง ดีใจที่ได้คิดถึงมันหลังจากห่างไปนาน
ดูเหมือนผู้เขียนจะสังเกตเห็นว่าประสิทธิภาพไม่ได้เพิ่มแบบเชิงเส้นตามค่า %CPU utilization และเลยสรุปว่า %CPU utilization เองเป็น “เรื่องโกหก”
ต่อให้ไม่มี hyperthread หรือการลด clock และแม้แต่ในกรณีอย่าง Apple silicon ที่ดูเหมือนมีตัวแปรน้อย ก็ยังไม่เกิด scaling แบบเป็นสัดส่วนเป๊ะ
พอเริ่มใช้หลายคอร์พร้อมกัน คอขวดจากทรัพยากรอื่นที่ไม่ใช่ CPU เช่น overhead ของการส่งต่อข้อมูล ก็มักโผล่มาสร้างปัญหาบ่อย ทำให้เกิดสถานการณ์แบบเดียวกันได้เสมอ
คำว่า core ที่ผู้เขียนใช้ค่อนข้างชวนสับสนและไม่ตรงมาตรฐาน
เขาเรียก 5900X ว่าเป็นระบบ 24 คอร์ แต่จริง ๆ แล้วเป็นโครงสร้างที่มี 12 คอร์จริงและ 24 hyperthread
12 ตัวแรกคือคอร์จริง ส่วนอีก 12 ตัวเป็นเธรดที่ทำงานแนบอยู่กับแต่ละคอร์
แม้ instruction pipeline จะมี 2 ชุด แต่ก็ยังแชร์ functional unit ภายในกันอยู่
หลายปีก่อน ตอนพยายามอธิบาย hyperthreading ให้弟ชายที่ไม่ค่อยรู้เรื่องนี้ฟัง ผมเคยเปรียบเทียบไว้แบบหนึ่งที่ยังจำได้ คือมันเหมือนกระดาษชำระแบบสองชั้น
คุณแยก 24 ม้วนออกมาต่างหากไม่ได้ แต่ก็เหมือนทำให้ของ 12 ม้วนมีประโยชน์มากขึ้นประมาณสองเท่า
หลังได้รับ feedback ก็แก้คำอธิบายเป็น 12 คอร์ / 24 เธรดแล้ว
แต่ยอมรับว่าที่สับสนก็เพราะ OS ของผมแสดง utilization เป็น 24 คอร์
ถ้า Intel ออกซอฟต์แวร์ที่นิยามคอร์ได้เองก็น่าจะน่าสนใจ
มันจะเป็นแนวคิดตรงข้ามกับ hyperthreading แบบเชิงตรรกะ คือเอาคอร์ตั้งแต่สองคอร์ขึ้นไปมาแชร์ทรัพยากรกันเพื่อแปลงเป็น “คอร์ใหญ่หนึ่งคอร์”
ดูลิงก์สิทธิบัตรด้านล่าง
https://patents.google.com/patent/EP4579444A1/en
ถ้าคู่ SMT รัน workload ประเภทเดียวกัน ผลของ SMT จะลดลงเพราะเกิดการแย่งทรัพยากรภายในและ execution unit
ถ้า workload ต่างกันอย่างสิ้นเชิง บางที boost อาจมากขึ้นด้วยซ้ำ
เดี๋ยวนี้ CPU รุ่นใหม่ยังมีตัวแปรอย่าง P-core, E-core, turbo/ไม่ turbo เพิ่มเข้ามา ทำให้เรื่องยิ่งซับซ้อน
เคยมีงานวิจัยบอกว่าการเพิ่ม SMT ให้ผลด้านประสิทธิภาพต่อวัตต์ดีกว่าการเพิ่ม turbo ซึ่งน่าสนใจมาก
เป็นเรื่องที่รู้สึกอินมากจริง ๆ
วันหนึ่งเมื่อก่อน ผมเคยต้องอธิบายให้ผู้จัดการฟังว่าแม้ CPU ของเซิร์ฟเวอร์จะอยู่ที่ 60% แต่ก็แทบไม่มีเผื่อแล้ว แล้วเขาก็มองกลับมาด้วยสีหน้าเหมือนงง ๆ
ตอนนั้นถ้ามีคำอธิบายแบบนี้ก็คงดีมาก
ถ้าอธิบายทฤษฎีคิวประกอบไปด้วยจะยิ่งเห็นภาพมาก
ต่ำกว่า 60% ความหน่วงจากการเข้าคิวแทบมองข้ามได้
พอเกิน 70% จะเริ่มรู้สึกถึงความหน่วงชัด และตั้งแต่ 80% ขึ้นไปแทบจะเพิ่มเป็นสองเท่า
จากประสบการณ์จริงของผม เราเล็งเป้าไว้ที่ 65% ตามค่า P95 time และมันใกล้เคียงกับเกณฑ์เชิงทฤษฎีมาก
สรุปเชิงปฏิบัติคือ “60% คือขีดจำกัดการใช้งาน, 80% ขึ้นไป latency พุ่งแรง”
แต่ทั้งหมดนี้ก็อาจต่างกันไปโดยสิ้นเชิงตาม workload
โดยเฉพาะยุคนี้ที่ CPU เซิร์ฟเวอร์มี 32 คอร์กันเป็นเรื่องปกติยิ่งต้องระวัง
มีหลายกรณีที่ CPU utilization ไม่ได้ทำงานอย่างที่คาด
ปกติถ้าเป็นบทความแนวนี้ ผมจะนึกว่าเป็นเรื่องค่าบน Linux/Windows ที่แสดง utilization วนไปมา แต่ในความเป็นจริงก็มีหลายกรณีที่ CPU ว่างอยู่หรือ downclock เพราะติดคอขวดที่ RAM
จริง ๆ แล้ว CPU utilization คือการที่ OS (ไม่ว่าจะ Windows หรือ Linux) วัดแค่ว่าจัดสรรเธรดไปลงแต่ละคอร์มากน้อยแค่ไหน
แต่ถึงเธรดนั้นจะรออยู่ใน
memcpyแบบ 100% ก็ยังถูกนับเป็น utilizationข้อดีของ hyperthread คือถ้าเธรดหนึ่งติดอยู่กับ AVX/vector unit ส่วนอีกเธรดหนึ่งติดกับงานง่าย ๆ อย่าง
memcpy/RAM ก็สามารถเพิ่มการใช้ unit แต่ละส่วนให้ดีขึ้น ทำให้ทั้งประสิทธิภาพรวมและ utilization สูงขึ้นได้สรุปแล้ว CPU Utilization เป็นหัวข้อที่เข้าใจได้ยากในเชิงสัญชาตญาณมานานมาก และก็ยังมีมุมมองใหม่ ๆ โผล่ออกมาเรื่อย ๆ
แต่ถึงอย่างนั้นก็เป็นหัวข้อที่น่าสนุกเสมอ
สิ่งที่เป็น “เรื่องโกหก” จริง ๆ คือการเชื่อว่า hyperthread core ทำงานเหมือนคอร์จริงทุกประการ
พอใช้งานกันมานานกว่า 20 ปี คนก็ลืมแก่นเดิมไป และค่อย ๆ ตระหนักซ้ำแล้วซ้ำเล่าว่าทำไมค่าประสิทธิภาพที่วัดได้ถึงดูแปลก
อีกอย่างหนึ่งคือ โดยพื้นฐานแล้วโปรเซสเซอร์มีแค่สถานะ “กำลังรัน” (100%) หรือ “กำลังรอ” (0%)
การให้ค่าเป็นเปอร์เซ็นต์ตรงกลางนั้นสุดท้ายก็เป็นเพียงค่าเฉลี่ยในช่วงเวลาหนึ่งเท่านั้น ซึ่งทำให้นึกย้อนกลับมาคิดได้เหมือนกัน
ผมเคยมีบทสนทนาแบบนี้มาก่อน
ผู้จัดการ: CPU utilization 100% งั้นควรเปลี่ยนเซิร์ฟเวอร์ไปใช้ instance ที่ใหญ่ขึ้นไหม
ผม: “แต่ตอนนี้ CPU กำลังทำงานที่มีประโยชน์จริงอยู่หรือเปล่า?”
สุดท้ายแล้ว busy waiting ก็ถูกนับเป็น CPU utilization ด้วย จึงมีหลายกรณีที่ตัวเลขขึ้นสูงทั้งที่ไม่เกี่ยวกับงานที่มีประโยชน์จริง
เป็นคำกล่าวที่ถูกต้อง