Domanda

Ho un programma Java per fare una serie di calcoli scientifici su più processori suddividendolo in pezzi ed eseguendo ogni pezzo in un thread diverso. Il problema è banalmente partizionabile, quindi non c'è contesa o comunicazione tra i thread. Gli unici dati comuni a cui accedono sono alcune cache statiche condivise che non necessitano di avere il loro accesso sincronizzato e alcuni file di dati sul disco rigido. I thread inoltre scrivono continuamente sul disco, ma per separare i file.

Il mio problema è che a volte quando eseguo il programma ottengo una velocità molto buona, e a volte quando eseguo esattamente la stessa cosa gira molto lentamente. Se lo vedo funzionare lentamente e Ctrl-C e lo riavvio, di solito ricomincerà a funzionare velocemente. Sembra essere impostato in modalità lenta o veloce all'inizio della corsa e non passa mai da una modalità all'altra.

L'ho collegato a jconsole e non sembra essere un problema di memoria. Quando l'ho notato funzionare lentamente, ho provato a connetterlo a un profiler ma il profiler non si connetterà. Ho provato a correre con -Xprof ma i dump tra una corsa lenta e una corsa veloce non sembrano essere molto diversi. Ho anche provato a utilizzare diversi garbage collector e diversi dimensionamenti delle varie parti dello spazio di memoria.

La mia macchina è un mac pro con partizione RAID con striping. L'utilizzo della cpu non diminuisce mai se sta funzionando lentamente o rapidamente, cosa che ti aspetteresti se i thread impiegassero troppo tempo a bloccare le letture dal disco, quindi non penso che potrebbe essere un problema di lettura del disco.

La mia domanda è: quali tipi di problemi con il mio codice potrebbero causare questo? O potrebbe essere un problema con il sistema operativo? Non sono stato in grado di duplicarlo su una macchina Windows, ma non ho una macchina Windows con una configurazione RAID simile.

È stato utile?

Soluzione

Potresti avere thread che sono entrati in un ciclo infinito.

Prova a connetterti con VisualVM e usa il monitor Thread.

https://visualvm.dev.java.net

Potrebbe essere necessario connettersi prima che si verifichi il problema.

Altri suggerimenti

Secondo, dovresti farlo con un profiler che guarda la vista dei thread - quanti thread, in quali stati si trovano, ecc. Potrebbe essere una strana condizione della razza che si verifica di tanto in tanto. Potrebbe anche essere il caso che la strumentazione delle classi con hook del profiler (che causa il rallentamento), risolva le condizioni della gara e non si vedrà alcun rallentamento con il profiler allegato: /

Dai un'occhiata a questo post , o meglio la risposta, in cui è menzionato il problema di contesa della cache.

Stai generando ogni volta la stessa massa di fili? Quel numero è inferiore o uguale al numero di thread disponibili sulla tua piattaforma? Quel numero potrebbe essere verificato o accreditato con una discreta precisione.

Si prega di pubblicare eventuali finidng!

Hai uno strumento per misurare la temperatura della CPU? Il sistema operativo potrebbe limitare la CPU per gestire i problemi di temperatura.

È possibile che il tuo programma venga impaginato su disco a volte? In questo caso, dovrai guardare l'utilizzo della memoria del sistema operativo nel suo complesso, piuttosto che solo il tuo programma. So per esperienza che c'è un'enorme differenza nelle prestazioni di runtime quando la memoria viene continuamente paginata sul disco e viceversa.

Non so molto su OSX, ma in Linux il "libero" il comando è utile per questo scopo.

Un altro problema che potrebbe causare questo rallentamento sono i file di registro? Ho conosciuto almeno un po 'di codice di registrazione che ha rallentato il sistema in modo incrementale con l'aumentare dei file di registro. È possibile che i thread si stiano sincronizzando su un file di registro di dimensioni crescenti, quindi quando si riavvia il programma, viene utilizzato un altro file di registro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top