PDA

View Full Version : [C] - Utilizzo programmi con processori dual core!!


marco83pt
07-12-2008, 22:09
Salve a tutti, vi voglio porre una domanda, forse anche banale, ma fatto sta che risposte anche con google non ne ho trovate (di chiare intendo). Sto sviluppando alcuni applicativi creati in C. Poiché fanno uso intensivo del processore (le elaborazioni mi durano qualche minuto) volevo sapere se fosse possibile, nei computer muniti di CPU dual core, compilarle in modo tale per cui una volta lanciate vadano ad usare entrambe in parallelo i due core della cpu e non soltanto uno solo.

Saluti, Marco.

Vincenzo1968
07-12-2008, 22:56
Ciao Marco,

Non è possibile farlo automaticamente con un'opzione del compilatore. Devi progettare l'applicazione in modalità multithreading.
Puoi utilizzare diverse librerie. Io preferisco OpenMP che è pienamenta supportata dalla maggior parte dei compilatori C, è portabile e di facile utilizzo:

http://openmp.org/wp/

http://en.wikipedia.org/wiki/OpenMP

http://msdn.microsoft.com/en-us/library/tt15eb9t.aspx

Intel Tutorials:
http://software.intel.com/en-us/articles/getting-started-with-openmp
http://software.intel.com/en-us/articles/more-work-sharing-with-openmp
http://software.intel.com/en-us/articles/advanced-openmp-programming

;)

Mattyfog
07-12-2008, 23:31
ma non sbasta creare più thread?

Unrue
08-12-2008, 09:28
Salve a tutti, vi voglio porre una domanda, forse anche banale, ma fatto sta che risposte anche con google non ne ho trovate (di chiare intendo). Sto sviluppando alcuni applicativi creati in C. Poiché fanno uso intensivo del processore (le elaborazioni mi durano qualche minuto) volevo sapere se fosse possibile, nei computer muniti di CPU dual core, compilarle in modo tale per cui una volta lanciate vadano ad usare entrambe in parallelo i due core della cpu e non soltanto uno solo.

Saluti, Marco.

Molte istruzioni sono passate in parallelo ai due core, sopratutto se non vi è dipendenza. Questo parallelismo è implementato in hardware. E' difficile però che le istruzioni non abbiano dipendenza, se non vengono scritte appositamente così.Si può però fare un parallelismo software con i thread, anche se ci pensa il sistema operativo a mappare thread sui vari core. Non ne hai controllo, se non con particolari opzioni più avanzate.

marco83pt
08-12-2008, 09:57
Oggi mi cimento con openMP. Vedo cosa tiro fuori.
Saluti.

Vincenzo1968
08-12-2008, 12:50
ma non sbasta creare più thread?

si, è possibile utilizzare le funzioni per la gestione dei thread. Su Windows, per esempio, si possono utilizzare le API CreateThread, etc, ma questo rende il codice non portabile.

marco83pt
09-12-2008, 09:26
Quindi in poche parole mi state dicendo che l'utilizzo di più thread in parallelo equivale ad usare entrambi i core della CPU???

banryu79
09-12-2008, 10:21
Quindi in poche parole mi state dicendo che l'utilizzo di più thread in parallelo equivale ad usare entrambi i core della CPU???


Per risponderti quoto quello che ha già scritto Unrue:

... Si può però fare un parallelismo software con i thread, anche se ci pensa il sistema operativo a mappare thread sui vari core. Non ne hai controllo, se non con particolari opzioni più avanzate.


In sostanza tu ti suddividi il lavoro nel tuo applicativo usando vari thread, ci penserà poi il S.O. a mappare i tuoi thread come meglio crede sui vari core.

Esattamente quale thread mappa in quale core a te non deve interessare, a meno di particolari esigenze ma in quel caso ti devi "sbattere" di più per avere quel tipo di controllo.

marco83pt
09-12-2008, 14:10
io ho fatto questi passaggi (banali passaggi):

void prodotto(long double** A, long double** B, long double** AB, int N) {
//Prodotto fra matrici
int i,j,k;
long double x;
#pragma omp parallel for default(none) private(i,j,k,x) shared(A,B,AB,N)
for(i = 0;i < N; ++i) {
for(j = 0;j < N; ++j) {
x = 0;
for(k = 0;k < N; ++k) {
x = A[ i ][ k ] * B[ k ][ j ] + x;
}
AB[ i ][ j ] = x;
}
}
}


il tempo di esecuzione è diventato un quarto...
bene....con così poco ho ottenuto così tanto.

gugoXX
09-12-2008, 14:17
Molte istruzioni sono passate in parallelo ai due core, sopratutto se non vi è dipendenza. Questo parallelismo è implementato in hardware. E' difficile però che le istruzioni non abbiano dipendenza, se non vengono scritte appositamente così.Si può però fare un parallelismo software con i thread, anche se ci pensa il sistema operativo a mappare thread sui vari core. Non ne hai controllo, se non con particolari opzioni più avanzate.

Occhio a non fare confusione tra il parallelismo delle pipeline, presente da un po' di generazioni, con quello dei Core.
La indipendenza delle istruzioni non e' condizione sufficiente per bilanciare il carico tra i diversi core.

shinya
09-12-2008, 14:30
il tempo di esecuzione è diventato un quarto...
bene....con così poco ho ottenuto così tanto.

Se il grosso del lavoro consiste nel moltiplicare delle matrici, potresti anche voler considerare algoritmi più efficienti di quello naive.

marco83pt
09-12-2008, 14:31
Se il grosso del lavoro consiste nel moltiplicare delle matrici, potresti anche voler considerare algoritmi più efficienti di quello naive.

tipo?

shinya
09-12-2008, 15:22
tipo?

Tipo:

http://en.wikipedia.org/wiki/Matrix_multiplication#Algorithms_for_efficient_matrix_multiplication

Ovviamente sono molto più complicati da implementare, vedi tu se ne vale la pena.

Vincenzo1968
09-12-2008, 17:17
io ho fatto questi passaggi (banali passaggi):

void prodotto(long double** A, long double** B, long double** AB, int N) {
//Prodotto fra matrici
int i,j,k;
long double x;
#pragma omp parallel for default(none) private(i,j,k,x) shared(A,B,AB,N)
for(i = 0;i < N; ++i) {
for(j = 0;j < N; ++j) {
x = 0;
for(k = 0;k < N; ++k) {
x = A[ i ][ k ] * B[ k ][ j ] + x;
}
AB[ i ][ j ] = x;
}
}
}


il tempo di esecuzione è diventato un quarto...
bene....con così poco ho ottenuto così tanto.

Il tuo è un ottimo esempio di quello che intendevo per facilità d'utilizzo. Utilizzando le API di Windows per i threads, avresti dovuto scrivere un bel po' di codice in più. ;)

P.S. per curiosità, in quale ambiente e con quale compilatore l'hai compilato?

^TiGeRShArK^
09-12-2008, 17:27
io ho fatto questi passaggi (banali passaggi):

void prodotto(long double** A, long double** B, long double** AB, int N) {
//Prodotto fra matrici
int i,j,k;
long double x;
#pragma omp parallel for default(none) private(i,j,k,x) shared(A,B,AB,N)
for(i = 0;i < N; ++i) {
for(j = 0;j < N; ++j) {
x = 0;
for(k = 0;k < N; ++k) {
x = A[ i ][ k ] * B[ k ][ j ] + x;
}
AB[ i ][ j ] = x;
}
}
}


il tempo di esecuzione è diventato un quarto...
bene....con così poco ho ottenuto così tanto.
beh..
in questo caso è banale..
prova ad implementare il parallelismo su programmi + complessi e vedi se non ti escono i capelli bianchi :asd:

Vincenzo1968
09-12-2008, 17:36
beh..
in questo caso è banale..
prova ad implementare il parallelismo su programmi + complessi e vedi se non ti escono i capelli bianchi :asd:

È ovvio che, se, per esempio, si utilizzano dei calcoli su una risorsa condivisa, bisogna organizzare il codice in modo da sincronizzare i thread. Ma con librerie come OpenMP il compito è, comunque, più facile rispetto all'utilizzo delle API.

:lamer:

Alex_87_xelA
09-12-2008, 17:41
Scusate ... in questo piccolo esempio fatto da marco83pt mi spiegate cosa fa un processore e cosa fa l'altro

mi potete spiegare il #pragma utilizzato come funziona ?

^TiGeRShArK^
09-12-2008, 18:04
È ovvio che, se, per esempio, si utilizzano dei calcoli su una risorsa condivisa, bisogna organizzare il codice in modo da sincronizzare i thread. Ma con librerie come OpenMP il compito è, comunque, più facile rispetto all'utilizzo delle API.

:lamer:
si, ma il problema vero è trovare i bug che si presenteranno sicuramente in software complessi...
le problematiche da affrontare in caso di codice multi-threaded sono moltissime, tanto è vero che praticamente tutti i sistemi per gestire l'interfaccia grafica girano in modalità single-thread (swing e windows forms in primis...)

^TiGeRShArK^
09-12-2008, 18:07
Scusate ... in questo piccolo esempio fatto da marco83pt mi spiegate cosa fa un processore e cosa fa l'altro

mi potete spiegare il #pragma utilizzato come funziona ?

mai usato openMP, ma a leggere il pragma si direbbe che definisce come risorse condivise le 3 matrici quadrate e la loro dimensione ed esegue in parallelo i 3 cicli for che utilizzano le variabili i,j,k come contatori e x che contiene il valore della moltiplicazione.

Vincenzo1968
09-12-2008, 18:14
si, ma il problema vero è trovare i bug che si presenteranno sicuramente in software complessi...
le problematiche da affrontare in caso di codice multi-threaded sono moltissime, tanto è vero che praticamente tutti i sistemi per gestire l'interfaccia grafica girano in modalità single-thread (swing e windows forms in primis...)

Concordo pienamente. Non voglio dire che librerie come OpenMP siano la manna dal cielo; soltanto, rendono un po' più facili le cose. Nell'esempio di Marco, per gestire le risorse condivise, è bastato elencarle nella clausola shared ;)
La programmazione multithreading richiede comunque, e con librerie particolari, e con le API, molta più attenzione rispetto a quella tradizionale.

:lamer:

gugoXX
09-12-2008, 18:15
Scusate ... in questo piccolo esempio fatto da marco83pt mi spiegate cosa fa un processore e cosa fa l'altro

mi potete spiegare il #pragma utilizzato come funziona ?

Diciamo che il primo for viene spaccato in 2 (se si hanno 2 core).
Il primo core svolgera' il for da 0 a N/2, il secondo da N/2 +1 a N
Poi in realta' la distribuzione del carico e gli indici effettivamente eseguiti dal singolo core non si sanno, dipende da come e' stata compilata la pragma
quello che e' certo e' che il corpo di un singolo indice del primo ciclo verra' svolto tutto da un ben specifico core di quelli a disposizione.

Per come si usa la OMP, che e' decisamente estesa, meglio leggere qualcosa.

Per poter funzionare bene e' necessario che i singoli task eseguiti siano indipendenti tra loro, come in questo caso (scrivere una particolare cella di una matrice che non verra' mai piu' scritta, ne letta da nessun altro task)
Fate pero' attenzione alle dipendenze implicite negli utilizzi di librerie come queste (come la PLINQ, p.es.)
Talvolta sembra che si stia agendo su celle di memoria tra loro scorrelate, ma in realta' una correlazione nascosta potrebbe esserci a livello di righe di cache, che forza il processore a rinfrescare le cache di secondo (o terzo) livello privata dei diversi core, annullando di fatto i benefici del parallelismo.
Mi e' gia' capitato, e prima di accorgersene...

Vincenzo1968
09-12-2008, 18:16
Scusate ... in questo piccolo esempio fatto da marco83pt mi spiegate cosa fa un processore e cosa fa l'altro

mi potete spiegare il #pragma utilizzato come funziona ?

Puoi vedere i tutorial che ho elencato nel mio primo post e anche questo:

http://www.codeproject.com/KB/cpp/BeginOpenMP.aspx

:lamer:

marco83pt
09-12-2008, 21:39
Ciao, rispondo solo ora e scusate. Il tutto è stato implementato in un pezzo di codice sorgente per l' inversione di matrici tramite metodo gauss-jordan (punto iniziale) e poi con passaggi iterativi per l'affinamento dovuto agli errori di arrotondamento. Grazie ai consigli vostri mi sono documentato un pò sulla faccenda openMP e comunque non mi sembra molto complesso, poiché come vi ripeto, sono bastati un analisi per scovare le indipendenze nei cicli for...ed una giusta sintassi.
Il compilatore usato è microsoft VS2008 (con l'opzione da riga di comando /openmp).
comunque sia girando per internet si trovano un sacco di appunti e dispense, anche se ritengo che un libro come primo approccio è sempre la scelta migliore.
L'esempio che ho riportato diciamo è la condizione più "banale", poiché lo stesso openmp ci mette anche a disposizione comandi per il controllo di flusso e sincronizzazione dei sincoli threads (per la stesura di un codice a regola d'arte)...comunque sono sempre all' inizio, e la faccenda è molto più complicata di quanto possa sembrare, ma è giuto trovare un compromesso fra quello che si vuole come obbiettivo,senza dover incasinarsi troppo la vita (ufficio complicazioni affari semplici :-)).
Un saluto e una buona serata.

Alex_87_xelA
09-12-2008, 21:50
GRAZIE RAGAZZI :D

Alex_87_xelA
09-12-2008, 21:56
scusate ragazzi posso farvi quest'altra domanda ?

la direttiva del preprocessore "#pragma" a cosa serve ?

so a cosa servono tutte le altre direttive come :
#if #elif #else #define #defined ... ma #pragma cosa fa ?

grazie per le vostre risposte.