Sayısal optimizasyon problemlerinin bir sınıfını çözmek için bir Java uygulaması üzerinde çalışıyorum - daha büyük olması için büyük ölçekli doğrusal programlama sorunları. Tek bir sorun, paralel olarak çözülebilen daha küçük alt sorunlara bölünebilir. CPU çekirdeklerinden daha fazla alt problem olduğundan, bir ExecutorService kullanıyorum ve her bir alt problemi ExecutorService'e gönderilen Callable olarak tanımlıyorum. Bir alt problemi çözmek için yerel kütüphanenin çağrılması gerekir - bu durumda doğrusal bir programlama çözücüsü.
Sorun
Uygulamayı Unix'de ve 44 fiziksel çekirdeğe ve 256 g'a kadar belleğe sahip Windows sistemlerinde çalıştırabilirim, ancak Windows'taki hesaplama süreleri, büyük sorunlar için Linux'tan daha büyük bir sıralamadır. Windows sadece önemli ölçüde daha fazla bellek gerektirmez, aynı zamanda zaman içinde CPU kullanımı birkaç saat sonra başlangıçta% 25'ten% 5'e düşer. Windows'daki görev yöneticisinin ekran görüntüsü:
Gözlemler
- Genel sorunun büyük örnekleri için çözüm süreleri saatler ila günler arasında değişir ve 32 g'a kadar bellek tüketir (Unix'te). Bir alt problemin çözüm süreleri ms aralığındadır.
- Çözülmesi sadece birkaç dakika süren küçük sorunlarda bu sorunla karşılaşmıyorum.
- Linux her iki soketi de kutudan çıkarırken kullanıyor; Windows, uygulamanın her iki çekirdeği kullanması için BIOS'ta bellek serpiştirmeyi açıkça etkinleştirmemi gerektiriyor. Bunu yapmamamın zaman içinde genel CPU kullanımının bozulması üzerinde hiçbir etkisi yoktur.
- VisualVM iş parçacıklarına baktığınızda tüm havuz iş parçacıkları çalışıyor, hiçbiri beklemede veya başka.
- VisualVM'ye göre,% 90 CPU zamanı yerel işlev çağrısında harcanıyor (küçük bir doğrusal programı çözme)
- Çöp Toplama bir sorun değildir çünkü uygulama çok fazla nesne oluşturmaz ve referansları kaldırmaz. Ayrıca, çoğu bellek yığın dışı tahsis gibi görünüyor. En büyük örnek için Linux'ta 4g yığın, Windows'ta 8g yığın yeterlidir.
Ne denedim
- her türlü JVM argümanı, yüksek XMS, yüksek metaspace, UseNUMA bayrağı, diğer GC'ler.
- farklı JVM'ler (Hotspot 8, 9, 10, 11).
- farklı doğrusal programlama çözücülerinin farklı yerel kütüphaneleri (CLP, Xpress, Cplex, Gurobi).
Sorular
- Yerel çağrıları yoğun şekilde kullanan çok iş parçacıklı büyük bir Java uygulamasının Linux ve Windows arasındaki performans farkını ne artırır?
- Örneğin Windows'a yardımcı olacak uygulamada değiştirebileceğim bir şey var mı, örneğin binlerce Callables alan bir ExecutorService kullanmaktan kaçınmalı mıyım?
ForkJoinPool
için manuel programlamaya göre daha verimlidir.
ForkJoinPool
Bunun yerine denedinExecutorService
mi? Sorununuz CPU'ya bağlıysa,% 25 CPU kullanımı gerçekten düşüktür.