Posso usare tutti e 4 i core della CPU del Raspberry Pi?


11

Mi chiedevo se esiste un modo semplice per "accendere" tutto il 100% della CPU in modo da poter eseguire i processi più velocemente (come i calcoli di Python).

1) è possibile?

2) C'è un modo semplice per tornare alla normalità?

3) C'è un modo per usare meno CPU se lo si desidera?

Sto pensando a un'interazione da riga di comando come:

pi@raspberry:~ $ sudo turnOnFourCores python run.py


1
La risposta breve è No
Steve Robillard il

16
La lunga risposta è "Se fosse così semplice, sarebbe l'impostazione predefinita"
Shadow

18
Entrambi i tuoi commenti sono fuorvianti e potrebbero implicare che il Pi ha 4 core ma utilizza sempre e solo 1. Una risposta migliore è che tutti e quattro i core SONO già attivi , ma che Python (e qualsiasi altro programma, del resto) ne utilizzerà solo di più di 1 core a meno che non siano multi-thread. Python può ancora essere bloccato efficacemente usando un singolo core anche con multi-threading a causa del blocco dell'interprete globale, ma questo è un po 'al di là dell'ambito di questa domanda.
Sohcahtoa82,

13
Per chiarire, penso che l'OP abbia un'incomprensione su come funzionano le CPU multi-core e le tue risposte non fanno che rafforzare il loro malinteso.
Sohcahtoa82,

6
Il modo più semplice per rendere più veloce un programma Python è riscrivere in un linguaggio compilato (o almeno fare in modo che le attività critiche utilizzino il modulo ac).
Milliways,

Risposte:


21

Per impostazione predefinita, qualsiasi computer proverà a utilizzare tutti i suoi core quando può. Tuttavia, può raggiungere questo obiettivo solo quando un'applicazione è multi-thread. In caso contrario (ovvero uno script Python che non utilizza il threadingmodulo), può utilizzare solo al massimo un core. Ciò equivale al 25% della CPU su una CPU a quattro core. Se desideri modificare lo script per utilizzare più core, puoi dividere il calcolo in più parti e multi-thread come mostrato nella documentazione di Python .

Aggiornare:

Come ha risposto Anon , questo non funzionerà senza lavorare con GIL (Global Interpreter Lock) di Python. Ciò consente alle attività di operare (apparentemente) contemporaneamente, ma non consente l'esecuzione del codice su più core. Se stai usando moduli scritti in C (ad esempio numpy), possono permetterti di usare più core aggirare quella limitazione. Inoltre, se questa non è un'opzione, Python offre il multiprocessing , che consente di eseguire qualsiasi attività su più core.


L'aggiornamento - che è corretto - spiega perché la prima parte della risposta è sbagliata rispetto a Python. Puoi aggirare questa limitazione di Python solo scrivendo i moduli C o un linguaggio compilato, a quel punto non stai più scrivendo Python. Se le prestazioni sono fondamentali, andare a un linguaggio compilato è la risposta giusta. (Il multiprocessing non è lo stesso dal punto di vista dell'utilizzo delle risorse.)
Brick,

4
@Brick Per essere chiari, un linguaggio compilato non è certamente un requisito per un corretto multithreading in-process. Diamine, anche GIL di Python è un dettaglio di implementazione (garantito, per il popolare CPython) - ci sono altri interpreti Python che saranno felicemente multithread, ad esempio Jython e IronPython.
Bob,

4
Aggiungendo alla confusione, Python viene compilato; nel caso di CPython si compila nel bytecode CPython che viene eseguito nella VM CPython. Per Jython, è compilato in bytecode Java che viene eseguito nella JVM. Infine, IronPython si compila in CIL, che ha come obiettivo il runtime .NET. Quindi, "andare in un linguaggio compilato" per la performance non ha davvero senso;)
marcelm

qualsiasi computer proverà a usare tutti i suoi core quando può. Non proprio, userà tutti i suoi core (o farà qualsiasi altra cosa) quando gli viene detto . Questa distinzione può sembrare ovvia o addirittura condiscendente per l'esperto, ma sembra che l'OP debba capire che non accade automaticamente.
Nekomatic

13

Mi chiedevo se esiste un modo semplice per "accendere" tutto il 100% della CPU in modo da poter eseguire i processi più velocemente (come i calcoli di Python).

Non nel senso che penso tu stia insinuando. Questo non è un problema specifico per il pi, è anche un vincolo logico.

Tutti i computer da soli attualmente non hanno molta capacità per determinare che un processo in esecuzione come singolo thread può invece essere eseguito in parallelo. Si noti che nel momento in cui potrebbero avere questa capacità, non ci sarebbe bisogno di programmatori di computer, perché un sistema informatico che potrebbe farlo potrebbe anche scrivere il proprio codice 1 ..

Considera la seguente semplice espressione matematica:

(4 + 2) * 17 / (3 + 6)

Esiste un potenziale per questo da calcolare in parallelo, ma è logicamente limitato. Direi che non ha senso in più di due thread, e anche allora sarà per lo più solo uno:

#1 a) 4 + 2 b) 6 * 17 c) 102 / 9
#2 a) 3 + 6

Il thread n. 2 ha contribuito calcolando 3 + 6 = 9, utilizzato nel passaggio C dal thread n. 1, salvandolo di un passaggio. Ma questo è quanto ci sarà utile il parallelismo qui. Mentre il thread n. 2 potrebbe calcolare 17/9 mentre il numero 1 sta eseguendo 6 * 17, ciò sarebbe inutile, perché ora hai due percorsi diversi per lo stesso obiettivo che non possono essere ricombinati. Vale a dire, # 2 potrebbe continuare a funzionare:

b) 17 / 9 c) 1.888 * 6

E finiscono con lo stesso risultato del thread n. 1 (11.333), ma non si sono aiutati a vicenda oltre il passaggio A, quindi avere due di loro a perseguire questo obiettivo è una perdita di tempo.

(Si noti che questo esempio non è letterale; intende dimostrare un principio logico. La scala su cui le attività sono inserite nel codice utente è molto più grande, ma non è necessaria una vera lezione di programmazione multi-thread per cogliere l'idea qui.)

Lo sfruttamento di più processori richiede il codice scritto per farlo. Non puoi semplicemente prendere nulla e dire "oh usa tutti e 4 i core e fallo più velocemente!". Non è quello che succederebbe. Logicamente, molti (e molti) problemi e compiti implicano passaggi che non possono avvenire in parallelo, ma devono avvenire in sequenza.


1. Ma vedi il commento di Felix Dombek di seguito; Non sono un esperto di AI. Potrebbe anche valere la pena notare che, secondo i commenti di Peter Corde, i sistemi operativi e i set di istruzioni contemporanei possono essere sfruttati dal sistema operativo per ottimizzare le cose in modo molto finemente parallelo, e anche le pipeline hardware lo fanno, anche se non attraverso i core (un singolo core ha più di una cosa in corso, operando sul flusso di istruzioni in vari punti prima della loro esecuzione finale). Stavo cercando di attenermi all'argomento dei thread degli utenti qui perché penso che sia più o meno quello a cui stai arrivando.


4
Ho scritto un sacco di codice numerico parallelo, e questo è un po 'fuorviante per quanto riguarda i dettagli. Non parallelizzare a livello di singole operazioni aritmetiche come questa. (Se ci espandiamo oltre Raspberry Pi, alcuni complier e processori già ne parallelizzeranno parte anche all'esterno delle strutture di threading.) Parallelizzate intere attività in blocchi più grandi.
Brick,

4
@Brick "Non si parallelizza a livello di singole operazioni aritmetiche come questa." -> Certo che no, ma renderò più esplicito che questa è un'analogia, non una lezione sulla programmazione multi-thread di dadi e bulloni.
Riccioli d'oro

4
Il parallelismo nel calcolo che usi come esempio è così localizzato che creerà parallelismo a livello di istruzione in un programma che lo calcola, e le CPU con esecuzione fuori ordine possono sfruttare tale parallelismo da sole.
Peter Cordes,

2
RPi3 utilizza un superscalar in ordine di 2 in en.wikipedia.org/wiki/ARM_Cortex-A53 , quindi con un'attenta pianificazione delle istruzioni un compilatore può comunque sfruttare l'ILP mettendo due addistruzioni una accanto all'altra in modo che entrambe possano funzionare nello stesso ciclo dell'orologio. Il seguente resto moltiplicare e dividere sarà serializzato dalle dipendenze dei dati, tuttavia, come sottolineato.
Peter Cordes,

1
Determinare parti parallelizzabili non richiede necessariamente un'intelligenza artificiale forte. In senso "generale", potrebbe; ma è facilmente immaginabile che i computer possano usare un approccio euristico che funziona principalmente in molti casi pratici. Ad esempio, un computer non ha dimostrato l'ultimo teorema di Fermat, ma certamente ci sono programmi proverti teorema. Si noti che i compilatori moderni per i linguaggi di programmazione eseguono già un sacco di riarrangiamento del codice come parte delle loro fasi di ottimizzazione, che implica il ragionamento su parti parallelizzabili.
Felix Dombek,

7

No per Python.

Altre persone ti stanno suggerendo di esaminare il threading, che è una risposta valida per la maggior parte delle lingue, ma non hanno preso in considerazione l'account che stai usando Python.

Python GIL non ti consente di utilizzare efficacemente più core.


3
GIL rende leggermente più difficile usare tutti e 4 i core. Non lo rende in alcun modo impossibile, o addirittura così impegnativo.
Nome falso

5

L'uso di più core richiede l'esposizione esplicita del parallelismo a livello di thread al sistema operativo, che di solito richiede al programmatore di scrivere un programma multi-thread. (O per eseguire un programma a thread singolo più volte su input diversi, come la compilazione con make -j4)

Tuttavia, i compilatori per alcune lingue supportano l'auto-parallelizzazione. Ad esempio, C o C ++ con OpenMP possono compilare un normale for()ciclo in un programma che avvia più thread.

#pragma omp parallel for
for(int i = 0; i < 1000000; ++i)
{
   A[i] = B[i] * constant + C[i];
}

Tuttavia, ciò deve accadere quando hai scritto o compilato il programma. Non è possibile che hardware e sistemi operativi attuali utilizzino più core per velocizzare un programma a thread singolo.


Correlati: come viene eseguito un singolo thread su più core? : risposta: non lo fanno. Esistono altri tipi di parallelismo, come il parallelismo a livello di istruzione che un singolo core della CPU trova e sfrutta per eseguire un singolo thread più velocemente di un'istruzione alla volta.

La mia risposta a questa domanda entra in alcuni dettagli di come le moderne CPU trovano e sfruttano il parallelismo a livello di istruzione a grana fine. (Principalmente focalizzato su x86). Questo è solo una parte del funzionamento delle normali CPU, avendo più istruzioni in volo contemporaneamente e non è qualcosa che devi abilitare in modo speciale. (Ci sono contatori delle prestazioni che possono farti vedere quante istruzioni per clock la tua CPU è riuscita a eseguire durante l'esecuzione di un programma o altre misure.)

Si noti che RPi3 utilizza core della CPU ARM Cortex-A53 in ordine . Ogni core è superscalare a 2 dimensioni (2 istruzioni per clock come ILP consente), ma non può riordinare le istruzioni per trovare più parallelismo a livello di istruzione e nascondere la latenza.

Tuttavia, la CPU è pipeline, quindi il numero totale di istruzioni in volo (dal recupero e decodifica fino alla fase di riscrittura alla fine della pipeline) è significativo. Quando le dipendenze dei dati non limitano le cose, ci possono essere 2 istruzioni in ogni fase della pipeline su cui la CPU sta lavorando, con un throughput di 2 istruzioni per clock. (Ecco cosa significa 2 in larghezza.)

Non può eseguire le istruzioni fuori servizio, ma con un attento ordinamento delle istruzioni (di solito da un compilatore) può comunque nascondere la latenza di un'istruzione che impiega più cicli affinché il suo output sia pronto. (ad esempio un carico anche se colpisce nella cache o una moltiplicazione richiederà più cicli, invece che un add sia pronto il ciclo successivo). Il trucco è ordinare le istruzioni asm in modo che ci siano più istruzioni indipendenti tra quella che produce un risultato e quella che lo utilizza.

Avere un software (un compilatore) che programma staticamente le istruzioni è più fragile che avere hardware che può riordinare internamente preservando l'illusione di funzionare nell'ordine del programma. È molto difficile per i compilatori fare un buon lavoro come anche una piccola finestra fuori servizio per le istruzioni di riordino perché i mancati cache sono imprevedibili ed è difficile analizzare le catene di dipendenze tra le chiamate di funzione al momento della compilazione. E il numero di registri è limitato senza rinominare i registri hardware.


Tutto questo è un piccolo conforto quando il tuo codice viene eseguito più lentamente di quanto desideri. Sicuramente ci sono molte cose interessanti sotto il cofano in un Cortex-A53, ma ci sono altre cose interessanti sotto il cofano in un Cortex-A57 (come l'esecuzione fuori servizio di un massimo di 3 istruzioni per orologio), e ancora di più in una grande CPU x86 come Skylake (per non parlare delle differenze di velocità di clock).

Cortex-A53 è piuttosto fantastico rispetto a un https://en.wikipedia.org/wiki/Classic_RISC_pipeline come MIPS originale di cui avresti imparato a studiare in classe di architettura informatica, ma per gli standard moderni è piuttosto di fascia bassa.


1
"Non è possibile che hardware e sistemi operativi attuali utilizzino più core per velocizzare un programma a thread singolo." non è STRETTAMENTE vero. Ad esempio, in un singolo programma Java con thread, Java può fare tutto il suo GC e analisi / compilazione di runtime su core CPU aggiuntivi. L'analisi di runtime è un grosso problema perché può decidere di effettuare alcune ottimizzazioni basate sull'esecuzione di percorsi di codice senza costare nulla al "singolo thread" e può accelerare notevolmente con ciò che apprende dall'analisi. In generale però il tuo punto è buono.
Bill K,

@BillK Per essere onesti, il "programma" in quel contesto è java, no myapp.jar, e certamente non è single thread.
Goldilocks

1
È vero, ho appena sottolineato che, a seconda di come è stato progettato il runtime, il "codice che scrivi", anche se a thread singolo, può sfruttare i core aggiuntivi senza codificarlo esplicitamente come un'app multi-thread. Python potrebbe fornire anche un runtime più potente ma sarebbe in qualche modo inutile. Non è comunque un grande salto - penso che anche Java utilizzi solo come 1/2 core aggiuntivo per dare una mano con una singola app thread.
Bill K,

" Non è possibile che hardware e sistemi operativi attuali utilizzino più core per velocizzare un programma a thread singolo. " E subito dopo spiegherai come l'hardware esegue le istruzioni in parallelo.
Thomas Weller,

3
@ThomasWeller Sì, ma per essere esigenti la pipeline del processore non utilizza più core; è contenuto in un core, ma consente di lavorare su più flussi di istruzioni. Cioè, è una forma di parallelismo, ma non è una forma di threading multi-core.
riccioli d'oro

4

Non è così che funzionano le CPU ... affatto.

Allo stato attuale, la tua CPU è perfettamente in grado di funzionare al 100% di utilizzo, supponendo che non sia strozzata a causa di problemi di temperatura a 80 gradi Celsius o più. Detto questo, non vuoi (generalmente) vedere la tua CPU ancorata al 100%. Se utilizzi regolarmente la CPU al 100%, probabilmente hai troppo da gestire per il tuo processore. Ciò causerà la balbuzie e un'esperienza utente generalmente infelice.

Per confrontare con qualcosa di più fisico, l'utilizzo della CPU è molto simile a un'auto. L'auto è probabilmente in grado di andare a 100 miglia all'ora, ma c'è una buona probabilità che il tachimetro legga qualcosa di significativo sotto questo. In città, potresti non essere mai in grado di ottenere circa 25 mph. Ciò non cambia, tuttavia, che l'auto può andare a 100 mph. Semplicemente non hai premuto l'acceleratore abbastanza forte.

Se fai semplicemente fare all'RPi più cose (spingi di più sull'acceleratore), vedrai aumentare la cifra di utilizzo della CPU. Ad esempio, osservare l'utilizzo della CPU quando si esegue il comando yesin una finestra del terminale (Ricordare che ctrl+ctermina i comandi del terminale). Ciò consentirà di aumentare la CPU del 25% in quanto massimizza uno dei quattro core della CPU.


5
Penso che questa risposta sia fuorviante dove si dice che in genere non si desidera che la CPU funzioni al 100% di utilizzo. Esistono molte applicazioni ad alta intensità numerica in cui si desidera assolutamente il 100% di utilizzo perché è stata dedicata la macchina (o le macchine) al calcolo. Per ottenere il vero tempo del supercomputer, devi spesso dimostrare che il tuo codice è ottimizzato abbastanza bene per farlo, altrimenti ti negheranno come uno spreco di risorse. Se hai un cluster Pi, ovviamente non stai ottenendo prestazioni da supercomputer, ma ciò potrebbe rendere più critico massimizzare l'utilizzo, non di meno!
Brick,

3
Sono in qualche modo d'accordo con Brick, nel senso che qui sembra implicito che se un processore è al 25%, è perché è per conservare il gas o obbedire al limite di velocità;) o essere educato e non sminuire le risorse. Potresti voler chiarire che è generalmente perché qualsiasi attività è in attesa di I / O per la maggior parte del tempo. Le cose che possono eseguire un singolo core fino in fondo lo faranno. Ciò che (idealmente) impedisce a questo di interrompere l'interfaccia utente è la suddivisione del tempo - ma realisticamente, è ancora abbastanza facile bloccare un piccolo computer single core.
Riccioli d'oro

L'utilizzo della CPU al 100% generalmente non causa una scarsa UX. Anche il 1000% può essere abbastanza buono poiché la maggior parte dei programmi non è limitata dalla CPU ma da altri fattori. Gli unici programmi che diventano lenti a causa di un carico estremo della CPU sono i programmi che utilizzano effettivamente la CPU per tutto il tempo.
Oskar Skog,

4

Le altre risposte forniscono buoni dettagli, ma non sembrano rispondere alle tue domande in modo specifico.

  1. Sì, se il programma (e il sistema operativo) sono programmati per tenere conto di più core. ('Threading' è il termine nella programmazione qui)
  2. La macchina utilizza quanto più o meno di ogni core di cui ha bisogno per completare l'attività. quindi non è necessario cambiare nulla.
  3. È possibile impostare limiti per l'utilizzo massimo, ma non è necessario in uso normale. Dai un'occhiata alle risposte qui: - /unix/151883/limiting-processes-to-not-exceed-more-than-10-of-cpu-usage

NB:

Se stai cercando di migliorare le prestazioni del pi in generale, potresti voler esaminare Overclocking. Ciò consente alla CPU di funzionare a una velocità maggiore. Gli svantaggi sono l'aumento della produzione di calore, la minore durata del processore e un aumento del consumo energetico.


2

Se possibile vorrei parametrizzare lo script ed eseguirli in processi Python separati. Per esempio:

cat parameters.txt | xargs -n1 -P4 python run.py

Un'altra alternativa è la libreria multiprocessing già menzionata, che consente di fork-and-join processi Python. Ma ciò richiede anche di avere un elenco di parametri (come un nome file) per cui si desidera eseguire i calcoli.


Prima parte: Sì, presumere che il problema in questione sia imbarazzantemente parallelo .
Peter Mortensen,

Ahaa vero, conoscevo solo il pool di elaborazione del multiprocessing mapma apparentemente ha anche molti costrutti di memoria condivisa piuttosto sofisticati.
NikoNyrh,


0

Se vuoi testare il tuo RPI. Puoi eseguire stresscome qui , quindi puoi vedere come vengono utilizzate le tue CPU htop. Questo è utile perché puoi vedere se la tua fonte di energia è sufficiente, se non è abbastanza il tuo RPI proverà ad usare troppa corrente (amperaggio) e si spegnerà.

D'altra parte, se vuoi usare lo scripting Python, dovresti vedere joblibquale funziona alla grande quando vuoi parallelizzare i processi, e quindi userai il numero di processori che desideri.


0

Sebbene tutte queste risposte siano corrette in diversi modi, è vero che il sistema operativo utilizzerà automaticamente i diversi core per distribuire il carico. Puoi vederlo con un semplice programma Python (temp.py dire)

while True:
  x = 1.0

apri un terminale dal tuo desktop RPi e digita $ topche mostrerà il lavoro del processore. Quindi apri un altro terminale e python3 temp.pyvedrai un processo python3 salire al 100% del tempo del processore. Quindi aprire un altro terminale e ripetere il processo e vedere come si sposta fino al 400%. Quindi a un livello come ha commentato @Shadow è così semplice ed è l'impostazione predefinita. Tuttavia, la progettazione di programmi che possono utilizzare l'elaborazione parallela non è banale, come altri hanno spiegato.


0

La risposta è un clamoroso SÌ! Devi semplicemente scrivere il tuo programma per riconoscerli e usarli. I programmi che lo fanno possono usare i core. Scrivo il mio per farlo in Java e così posso.

Le risposte di cui sopra dagli sviluppatori Python hanno un concetto molto limitato di questa risposta e quindi possono essere molto confuse, ma la risposta è SÌ e solo SÌ!


Puoi per favore elaborare?
SDsolar,

0

Dal momento che l'OP non ha specificato Python nella sua domanda, vorrei suggerire altri due linguaggi moderni che funzionano bene su Raspberry Pi e hanno modi molto semplici di usare la concorrenza.

Il mio preferito attuale è il linguaggio Rust. Ho scritto e compilato programmi sul Pi. Rust è bello in quanto previene molti tipi di puntatori e bug relativi alle condizioni di gara, il che rende la scrittura di codice simultaneo sia più semplice che più sicura. Rust è inteso come linguaggio di programmazione dei sistemi, ma può fare praticamente tutto ciò che C può fare.

Un'altra lingua simile è Go (chiamata anche Golang per semplificare la ricerca). Go è stato creato dal team di Google ed è una lingua abbastanza matura. È facile creare coroutine in Go, che chiamano "Go routine".

Entrambe queste lingue possono compilare il codice sul Raspberry Pi, anche sul Pi Zero. Tuttavia, possono entrambi essere compilati in modo incrociato da un computer più veloce, il che è utile per programmi di grandi dimensioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.