Domanda

Ho scritto un programma multi-thread che esegue un calcolo pesante della CPU con molte operazioni in virgola mobile. Più specificamente, è un programma che confronta sequenze di animazione fotogramma per fotogramma. Cioè confronta i dati dei fotogrammi dall'animazione A con tutti i fotogrammi nell'animazione B, per tutti i fotogrammi nell'animazione A. Eseguo questa intensa operazione per diverse animazioni in parallelo, quindi il programma può funzionare su una coppia AB, una coppia BC e una coppia CA in parallelo. Il programma utilizza QtConcurrent e una "mappa" funzione che mappa un contenitore con movimenti su una funzione. QtConcurrent gestisce il pool di thread per me, sto lavorando su un processore Intel Quad Core in modo da generare 4 thread.

Ora, il problema è che il mio processo distrugge la mia CPU. L'utilizzo è costante al 100% e in realtà ottengo una schermata blu della morte se eseguo il mio programma su una serie abbastanza grande di movimenti (errore di pagina nell'area non paginata). Sospetto che ciò sia dovuto al fatto che il mio computer è overcloccato. Tuttavia, questo potrebbe essere dovuto al modo in cui ho codificato il mio programma? Alcuni strumenti benchamrking molto intensi che ho usato per testare la stabilità della mia macchina non hanno mai bloccato il PC. Esiste un modo per controllare come il mio programma utilizza la mia CPU per ridurre il carico? O forse sto fraintendendo il mio problema?

È stato utile?

Soluzione

Ci sono alcune risposte eccellenti qui.

Vorrei solo aggiungere, dal punto di vista della messa a punto di un tuning delle prestazioni, a meno che ogni thread non sia stato ottimizzato in modo aggressivo, è probabile che abbia molto spazio per la riduzione del ciclo.

Per fare un'analogia con una gara automobilistica a lunga distanza, ci sono due modi per provare a vincere:

  1. Rendi l'auto più veloce
  2. Effettua meno soste e spostamenti secondari

Nella mia esperienza, la maggior parte del software come scritto per la prima volta è piuttosto lontano dal prendere la strada più diretta, specialmente man mano che il software diventa grande.

Trovare cicli sprecati nel tuo programma, come diceva Kenneth Cochran, non indovinare mai. Se risolvi qualcosa senza aver dimostrato che si tratta di un problema, stai investendo in un'ipotesi.

Il modo popolare per trovare problemi di prestazioni è usare i profiler.

Tuttavia, lo faccio molto e il mio metodo è questo: http: //www.wikihow.com/Optimize-Your-Program%27s-Performance

Altri suggerimenti

I PC con overclocking possono portare a tutti i tipi di strani problemi. Se sospetti che sia la causa principale del problema, prova a sincronizzarlo in intervalli ragionevoli e riprova a eseguire i test.

Potrebbe anche essere una sorta di strano baco di memoria in cui si corrompe la RAM in un modo in cui Windows (suppongo che il sistema operativo, a causa di BSOD) non sia più in grado di ripristinare (molto improbabile, ma chi lo sa).

Un'altra possibilità che mi viene in mente è che hai qualche errore nella tua implementazione del thread che uccide Windows.

Ma all'inizio, darei un'occhiata al problema dell'overclocking ...

il tipo di operazione che hai descritto è già altamente parallelizzabile. L'esecuzione di più di un lavoro può effettivamente danneggiare le prestazioni. Il motivo è dovuto al fatto che la cache di qualsiasi processore ha dimensioni limitate e più si tenta di eseguire contemporaneamente, più piccola diventa la condivisione della cache di ciascun thread.

Puoi anche esaminare le opzioni usando la tua GPU per assorbire parte del carico di elaborazione. Le GPU moderne sono notevolmente più efficienti per la maggior parte dei tipi di trasformazione video rispetto alle CPU di generazioni simili.

  

Sospetto che ciò sia dovuto al fatto che il mio computer è overcloccato.

È sicuramente possibile. Prova a impostarlo alla velocità normale per un po '.

  

potrebbe essere dovuto al modo in cui ho codificato il mio programma?

È improbabile che un programma in esecuzione in modalità utente provochi un BSOD.

Direi che non stai usando una macchina a 3 core (o 4, dato il 100% di utilizzo), e il parallelismo danneggerebbe attivamente le tue prestazioni se usi più thread che core. Crea solo un thread per core della CPU e qualunque cosa tu faccia, non avrai mai accesso ai dati da thread diversi contemporaneamente . Gli algoritmi di blocco della cache nella maggior parte delle CPU multi-core macelleranno assolutamente le tue prestazioni. In questo caso, su una CPU N-core che elabora animazioni L-frame, utilizzerei il thread 1 sui frame 0- (L / N), il thread 2 sui frame (L / N) - (2 * L / N),. .. filetto N sui telai ((N-1) * L / N) -L. Esegui le diverse combinazioni (A-B, B-C, C-A) in sequenza in modo da non bloccare la cache, inoltre, dovrebbe essere più semplice da codificare.

Come nota a margine? Il vero calcolo come questo dovrebbe utilizzare una CPU al 100%, significa che sta andando il più velocemente possibile.

L'overclocking è la causa più probabile dell'instabilità. Con qualsiasi algoritmo ad alta intensità di CPU ci sarà un certo thrashing della CPU. Nonostante l'overclocking, troverei un buon profiler delle prestazioni per trovare i colli di bottiglia delle prestazioni. Non indovinare mai dove si trova il problema. Potresti impiegare mesi a ottimizzare qualcosa che non ha alcun effetto reale sulle prestazioni o prestazioni peggiori potrebbero addirittura diminuire.

È fin troppo facile incolpare l'hardware. Ti suggerirei di provare a eseguire il tuo programma su un sistema diverso e vedere come andranno a finire con gli stessi dati.

Probabilmente hai un bug.

Cerca di utilizzare le operazioni SIMD. Penso che vorresti SSE in questo caso. Sono spesso un primo passo migliore della parallelizzazione in quanto sono più facili da correggere e forniscono una spinta considerevole alla maggior parte delle operazioni di algebra lineare.

Una volta ottenuto usando SIMD, guarda in parallelismo. Sembra che tu stia sbattendo anche la CPU, quindi potresti forse fare un po 'di sonno invece di attese occupate e assicurarti di ripulire o riutilizzare correttamente i thread.

Con l'assenza del codice di errore BSOD (utile per la ricerca) è un po 'più difficile aiutarti con questo.

Potresti provare a ripristinare fisicamente la tua memoria ((estraila e rilasciala). Io e alcuni altri che conosco ho lavorato su alcune macchine dove era necessario. Ad esempio, una volta ho provato ad aggiornare OS X su una macchina e continuava a schiantarsi ... finalmente ho saltato fuori la memoria e l'ho rimessa dentro e tutto andava bene.

Il sonno (1); dimezzerà l'utilizzo della CPU. Ho riscontrato lo stesso problema lavorando con un algoritmo ad alta intensità di CPU.

Se il tuo processore ha due o più core, puoi andare al task manager e andare ai processi e fare clic con il tasto destro sul nome del programma e fare clic su Imposta affinità e impostare il programma in modo da utilizzare un numero inferiore di core.

Ci vorrà più tempo per fare le azioni che stai chiedendo, ma causerà una diminuzione SIGNIFICATIVA nell'uso della CPU.

Penso che la schermata blu della morte sia causata quando la regione di memoria del kernel viene danneggiata. Pertanto, l'utilizzo del multithreading per eseguire operazioni parallele non potrebbe essere la ragione di ciò.

Bene, se stai creando più thread ciascuno con pesanti operazioni in virgola mobile, sicuramente l'utilizzo della CPU raggiungerà fino al 100%.

Sarebbe meglio se potessi dormire un po 'in ogni thread in modo che altri processi abbiano qualche possibilità. Puoi anche provare a ridurre la priorità dei thread.

Se nella piattaforma Windows, dopo un po 'di lavoro metti una chiamata alla funzione per informare la CPU che vuoi rendere la CPU ad altri processi. Effettuare una chiamata per dormire in questo modo:

Slepp (0);

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