My question is if the CPU hits 100% usage, are the 10 instances still being parallel processed?
Sì.
Or Does the CPU start sequencing them instead of parallel processing them?
Probabilmente il tuo processore non ha 10 core CPU, quindi sì, lo sta facendo anche in alcune sequenze. Ma improvvisamente non esegue un thread fino al completamento quando arriva al 100%. Sta usando lo swap per dare ad ogni thread una sezione temporale ; e lo fa se è al 100% o no.
Am I better off simply reducing the number of instances till the CPU usage is less than 100%?
No, vuoi il 100% di utilizzo della CPU, oppure stai sprecando cicli!
Tuttavia, questo non è nemmeno vicino all'intera storia e, al 100%, la CPU non è una grande misura dell'efficienza dei cicli della CPU che vengono utilizzati.
Probabilmente dovresti eseguire tutti i thread del processore con core CPU. (Se si utilizzano processi a thread singolo, contarli come thread). Quando si esegue più di questo, il sistema operativo scambia i thread dentro e fuori i core della CPU in un equilibrio di equità e altre politiche che assegna a ciascun thread un fetta di tempo qua e là.
Lo swapping causa vari tipi di overhead: overhead diretto mentre i cicli vengono sprecati facendo swap invece del lavoro, e overhead indiretto, che ha a che fare con il funzionamento delle cache: le memorie a più alta velocità direttamente sul processore. Le cache formano un livello della gerarchia di memoria, che include anche la memoria principale (i 16+ GB di RAM) e in definitiva include anche il disco come forma di memoria. L'utilizzo della gerarchia della memoria è la chiave per il throughput delle prestazioni.
Poiché ogni thread viene eseguito per un po 'di tempo, occuperà parte della cache per i propri scopi. In un certo senso, la cache si sta scaldando fino a quel thread, e questo è buono.
Quando il sistema operativo è in grado, fornirà una porzione di tempo consecutivo allo stesso thread sullo stesso processore, e il thread avrà una cache calda per iniziare.
Troppi thread in una volta causano l'annullamento dell'inquinamento della cache dovuto al fatto che vengono scambiati: quando un thread viene scambiato per la prima volta, la cache si raffredderà e dovrà scaldarsi prima di arrivare a miglior rendimento.
Tuttavia, elaborare un set di dati di grandi dimensioni in modo efficiente non richiede solo la gestione dei core ma anche un utilizzo migliore della gerarchia della memoria.
Un approccio per trovare un buon modo per suddividere il lavoro, che puoi modificare e perfezionare in base ai tempi, è qualcosa di simile a questo:
Dividi l'intero lavoro in una dimensione del blocco della dimensione della cache del processore di grandi dimensioni (L3, forse).
Quindi dividi ogni pezzo di lavoro in sezioni di tutti i processori che il processore ha (ad esempio 2, 4) ed esegui quelli. Quindi, al completamento di tali sezioni, esegui le sezioni successive del blocco successivo.
Molto ha a che fare con il carico di lavoro e l'architettura della cache. È probabile che le cache L1 più piccole vengano replicate e ciascuna dedicata a un particolare core della CPU; le cache L2 e L3 più grandi possono essere condivise da tutti i core, anche se potenzialmente con restrizioni tali che un core CPU non affama gli altri.
Va a come il carico di lavoro specifico viene eseguito sulla specifica architettura della cache sulla macchina in questione. Quindi, suddividere i pezzi per la dimensione L3 potrebbe funzionare bene, ma i pezzi della dimensione L2 potrebbero funzionare meglio.
Una sola applicazione / carico di lavoro può accedere alla sua sezione più e più volte in modo più o meno casuale, mentre una diversa applicazione / carico di lavoro può essere eseguita solo in serie attraverso la sezione dall'inizio alla fine. Questi diversi carichi di lavoro hanno aspetti di efficienza diversi nella gerarchia della memoria, quindi suddividerli in un modo diverso potrebbe aiutare o danneggiare l'uno o l'altro carico di lavoro.
Ci sono anche misure migliori che potresti voler prendere usando vari strumenti.