ฉันกำลังทำงานกับแอปพลิเคชัน Java เพื่อแก้ปัญหาการเพิ่มประสิทธิภาพเชิงตัวเลข - ปัญหาการเขียนโปรแกรมเชิงเส้นขนาดใหญ่ให้แม่นยำยิ่งขึ้น ปัญหาเดียวสามารถแบ่งออกเป็นปัญหาย่อยที่เล็กกว่าที่สามารถแก้ไขได้ในแบบคู่ขนาน เนื่องจากมีปัญหาย่อยมากกว่าคอร์ CPU ฉันจึงใช้ ExecutorService และกำหนดแต่ละปัญหาย่อยเป็น Callable ที่ได้รับการส่งไปยัง ExecutorService การแก้ปัญหาย่อยต้องเรียกไลบรารี่เนทีฟซึ่งเป็นตัวแก้ปัญหาการโปรแกรมเชิงเส้นในกรณีนี้
ปัญหา
ฉันสามารถรันแอพพลิเคชั่นบน Unix และระบบ Windows ที่มีฟิสิคัลคอร์สูงสุด 44 คอร์และหน่วยความจำสูงสุด 256g แต่เวลาในการคำนวณบนวินโดวส์นั้นมีลำดับความสำคัญสูงกว่าบน Linux สำหรับปัญหาใหญ่ Windows ไม่เพียง แต่ต้องใช้หน่วยความจำเพิ่มมากขึ้น แต่การใช้งาน CPU ในช่วงเวลานั้นลดลงจาก 25% ในช่วงเริ่มต้นเป็น 5% หลังจากผ่านไปสองสามชั่วโมง นี่คือภาพหน้าจอของตัวจัดการงานใน Windows:
ข้อสังเกต
- เวลาในการแก้ปัญหาสำหรับอินสแตนซ์ขนาดใหญ่ของปัญหาโดยรวมอยู่ในช่วงชั่วโมงต่อวันและใช้หน่วยความจำมากถึง 32 กรัม (บน Unix) เวลาแก้ปัญหาสำหรับปัญหาย่อยอยู่ในช่วง ms
- ฉันไม่พบปัญหานี้ในปัญหาเล็ก ๆ ที่ใช้เวลาเพียงไม่กี่นาทีในการแก้ไข
- Linux ใช้ทั้งสองซ็อกเก็ตนอกกรอบในขณะที่ Windows ต้องการให้ฉันเปิดใช้งานหน่วยความจำ interleaving ใน BIOS อย่างชัดเจนเพื่อให้แอปพลิเคชันใช้ประโยชน์จากทั้งสองคอร์ ไม่ว่าฉันจะทำสิ่งนี้หรือไม่ไม่มีผลต่อการเสื่อมสภาพของการใช้งาน CPU โดยรวมเมื่อเวลาผ่านไป
- เมื่อฉันดูเธรดใน VisualVM เธรดพูลทั้งหมดกำลังทำงานไม่มีใครรอหรืออย่างอื่น
- ตาม VisualVM เวลา CPU 90% ใช้ในการเรียกใช้ฟังก์ชันดั้งเดิม (การแก้ปัญหาโปรแกรมเชิงเส้นขนาดเล็ก)
- การรวบรวมขยะไม่ใช่ปัญหาเนื่องจากแอปพลิเคชันไม่ได้สร้างและอ้างอิงวัตถุจำนวนมาก นอกจากนี้หน่วยความจำส่วนใหญ่ดูเหมือนว่าจะถูกจัดสรรออกนอกกอง ฮีป 4 กรัมเพียงพอบน Linux และ 8g บน Windows สำหรับอินสแตนซ์ที่ใหญ่ที่สุด
สิ่งที่ฉันได้ลอง
- JVM args ทุกประเภท, XMS สูง, metaspace สูง, ธง UseNUMA, GC อื่น ๆ
- JVMs ที่แตกต่างกัน (Hotspot 8, 9, 10, 11)
- ไลบรารี่ต่าง ๆ ของตัวแก้ปัญหาการโปรแกรมเชิงเส้น (CLP, Xpress, Cplex, Gurobi)
คำถาม
- อะไรที่ทำให้ความแตกต่างด้านประสิทธิภาพระหว่าง Linux และ Windows ของแอพพลิเคชั่น Java แบบมัลติเธรดขนาดใหญ่ที่ใช้การโทรแบบเนทีฟจำนวนมาก
- มีสิ่งใดบ้างที่ฉันสามารถเปลี่ยนแปลงได้ในการใช้งานที่จะช่วย Windows เช่นฉันควรหลีกเลี่ยงการใช้ ExecutorService ที่ได้รับ Callables นับพันและทำสิ่งใดแทน
ForkJoinPool
มีประสิทธิภาพมากกว่าการตั้งเวลาด้วยตนเอง
ForkJoinPool
แทนExecutorService
? การใช้ CPU 25% นั้นต่ำมากหากปัญหาของคุณเกิดจาก CPU