Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Consiglio parallelizzazione codice con pthread
Forum - C/C++ - Consiglio parallelizzazione codice con pthread

Avatar
2_rici (Normal User)
Newbie


Messaggi: 11
Iscritto: 16/12/2010

Segnala al moderatore
Postato alle 20:29
Giovedì, 06/01/2011
salve a tutti,
mi sto accingendo a parallelizare delle parti del mio codice.
Volevo però un consiglio su come farlo in quanto le alcune prove che ho fatto non mi hanno soddisfatto molto.
Spiego velocemente il contesto.
Ho un file output_ls contente nomi di immagini, leggo linea per linea e richiamo la funzione sift che mi crea un file di testo contenente i sift.
Il mio non è tanto un problema di come fare con i thread più che altro qual'è la soluzione migliore, io avevo pensato di leggere una linea e passarla al thread che si occupi del sift e nel mentre passare un altra linea.
Mi è venuta fuori una cosa del genere che però mi pare vada sempre in seriale : (

Codice sorgente - presumibilmente Delphi

  1. void *sift_thread (void* st) {
  2.        
  3.         char* str;
  4.         string name;
  5.         size_t split;
  6.         string pgm="../Sift_Immagini/";
  7.         string pgm_C=pgm;
  8.         str = (char*) st;
  9.         string line(str);
  10.         if ( line != "") {
  11.         split = line.find_last_of(".");             //parte necessaria
  12.         name = line.substr(0, split);                 // per comporre il nome
  13.         pgm_C += name;                                // da passare alla
  14.         pgm_C += ".pgm";                              //  sift correttamente
  15.         sift_extract("../siftpp/glx/sift",pgm_C.c_str());
  16.         pgm_C = pgm;
  17.  
  18.         }
  19.         pthread_exit(0);
  20. }      
  21.  
  22.  
  23. void sift (void) {
  24.         string line;
  25.         char st[20];
  26.         pthread_t threads[NUM_THREADS];
  27.     int rc;
  28.     int t=0;
  29.         pthread_mutex_init(&mutexsum, NULL);
  30.         ifstream in("../output_ls");
  31.         while ( in.good() ) {                                  
  32.         t++;
  33.         getline(in,line);                             //lettura linea
  34.         strcpy(st,line.c_str());
  35.         rc = pthread_create(&threads[t], NULL, sift_thread, (void*)st);
  36.       }
  37.      
  38.      for (int i=0; i<t; i++) {
  39.       pthread_join(threads[i], NULL);
  40.    }
  41.  }



è un codice un pò improvvisato con nomi di variabile ancora molto "fantasiosi" per brutta abitudine faccio pulizia del codice quasi sempre verso la fine :_doubt:
spero comunque di essermi spiegato.

grazie!
Saluti
        Riccardo


p.s: non capisco come mai mi da presumibilmente codice Delphi :-?


Ultima modifica effettuata da 2_rici il 06/01/2011 alle 20:33
PM
Avatar
Shutdown (Founder Member)
Guru


Messaggi: 1212
Iscritto: 10/09/2005

Up
0
Down
V
Segnala al moderatore
Postato alle 0:01
Venerdì, 07/01/2011


1 + 1 = 10
PM
Avatar
Xaratroom (Ex-Member)
Expert


Messaggi: 526
Iscritto: 03/04/2008

Up
0
Down
V
Segnala al moderatore
Postato alle 1:05
Venerdì, 07/01/2011
Testo quotato


Ho un file output_ls contente nomi di immagini, leggo linea per linea e richiamo la funzione sift che mi crea un file di testo contenente i sift.
Il mio non è tanto un problema di come fare con i thread più che altro qual'è la soluzione migliore, io avevo pensato di leggere una linea e passarla al thread che si occupi del sift e nel mentre passare un altra linea.
Mi è venuta fuori una cosa del genere che però mi pare vada sempre in seriale : (


La lettura da file è molto più lenta, quindi, mi sembra del tutto plausibile che l'esecuzione possa sembrare seriale. Fai fare qualcosa di più lento al tuo thread e poi facci sapere.

Una soluzione migliore non c'è... io rimuoverei il thread, ovviamente la scelta dipende anche da quello che deve fare il programma intero.


bool Woman::makeYourselfBetter() {
       goto bathroom;

bathroom:
       while (1);

       return this->_isGoodResult();
}
PM
Avatar
2_rici (Normal User)
Newbie


Messaggi: 11
Iscritto: 16/12/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 15:06
Venerdì, 07/01/2011
Testo quotato

Postato originariamente da Shutdown:

Dai un'occhiata qui https://computing.llnl.gov/tutorials/pthreads/.



già letto, tre quarti delle cose che so su i thread vengono proprio da qui :k:

i thread fanno già qualcosa di più lento infatti la sift extract scrive su di un file all'incirca un migliaio di righe.
Processando 5 immagini da seriale a parallelo guadagno 3 secondi quando mi aspettavo un pò di più, ho provato allora ad aumentare il numero delle immagini per vedere i risultati ma sono occorso in un errore,
infatti con 13 immagini quando lo mando in esecuzione mi da
Codice sorgente - presumibilmente Plain Text

  1. *** stack smashing detected ***: ./a.out terminated



creo troppi thread? mi piaceva l'idea di avere un thread che si occupa di una sola immagine ! mi aspettavo così che tutti iniziassero la scrittura del file e si passassero il controllo man a mano.
come potrei fare?

comunque il programma finito è un progetto per l'università ed essendo un programma molto pesante (al momento impiego 330secondi per 11 immagini) i thread mi sembravano una cosa da inseririci per fare in modo di migliorare un pò le prestazioni ! ;)

PM
Avatar
Xaratroom (Ex-Member)
Expert


Messaggi: 526
Iscritto: 03/04/2008

Up
0
Down
V
Segnala al moderatore
Postato alle 22:14
Giovedì, 13/01/2011
Testo quotato


creo troppi thread? mi piaceva l'idea di avere un thread che si occupa di una sola immagine ! mi aspettavo così che tutti iniziassero la scrittura del file e si passassero il controllo man a mano.
come potrei fare?


Si. esiste un massimo numero di thread per processo.... puoi creare più processi che a loro volta si occupano di lanciare diversi thread.

La velocità dipende da tanti fattori... Se il tuo programma utilizza tanto l'hd allora il principale motivo di lentezza è quello, poi ovviamente, non avendo visto il codice, non posso dirti di più.


bool Woman::makeYourselfBetter() {
       goto bathroom;

bathroom:
       while (1);

       return this->_isGoodResult();
}
PM
Avatar
2_rici (Normal User)
Newbie


Messaggi: 11
Iscritto: 16/12/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 16:56
Venerdì, 14/01/2011
ho cambiato un pò tutto, creo un gruppo di thread (ora ne ho fissati 6) a cui passo l'indice della riga da leggersi così che si occupano ognuno del suo file, raggiungono poi una bariera e ricominciano da capo con un nuovo "set" di righe da processare fino alla fine del file. Dato che il numero di righe non sarà quasi mai un multiplo perfetto di 6 ho un controllo sulla creazione dei thread basato sul numero effettivo di righe ( es: se ho 10 righe la prima volta creo 6 thread che si occupano delle loro righe, poi ne creo solo 4 per le restanti ).

Non mi piace però che ogni thread si debba aprire la sua connessione al file per leggere la riga designatagli se questa connessione fosse condivisa credo che guadagnerei qualcosa in prestazioni.

sempre con i pthread sono arrivato ad un altro problema:

in un altro metodo devo riempire due matrici con valori presi da un file di testo (12000 * 128 campi circa) essendo che devo farlo sempre per 2 matrici ogni volta che viene invocato ho pensato di far fare questo lavoro a 2 thread distinti in parallelo (ognuno riempie la sua matrice)
il riempimento lo faccio così
Codice sorgente - presumibilmente C++

  1. void *fillMatrixWithSift(void *app){
  2.        
  3.         struct matrix *fill;
  4.         fill = (struct matrix *) app;
  5.  
  6.         const char *file = fill->stringa;
  7.         int n = fill->dimensione;      
  8.         int **val = fill->M;
  9.     fstream filestr;
  10.     float trash;
  11.     filestr.open (file, fstream::in);
  12.  
  13.  //#pragma omp parallel for num_threads (THREADS)
  14.     for(int i=0;i<n;i++){
  15.         for(int j=0;j<4;j++){
  16.         filestr >> trash;
  17.         }
  18.         for(int j=0; j<128;j++){
  19.         filestr >> val[i][j];
  20.         }
  21.     }
  22.     filestr.close();   
  23.     pthread_exit((void*) val);
  24. }



la matrice però non si riempiva correttamente e sono giunto alla conclusione che è per colpa del openMP infatti commetandolo la matrice si riempie correttamente.
Il problema è che inserendo i thread e commentando l'openMP ottengo le stesse prestazioni che creando le matrici serialmente e riempiendole con l'openMP  :_doubt:
quindi vorrei poter usare i due thread che a sua volta si suddividono il ciclo for con l'openMP però non capisco a cosa si debba il riempimento della matrice errato ( alcune righe sono corrette altre tutte a 0 )

spero di essermi circa spiegato :-|

PM
Avatar
Xaratroom (Ex-Member)
Expert


Messaggi: 526
Iscritto: 03/04/2008

Up
0
Down
V
Segnala al moderatore
Postato alle 9:46
Giovedì, 20/01/2011
Testo quotato

Postato originariamente da 2_rici:
la matrice però non si riempiva correttamente e sono giunto alla conclusione che è per colpa del openMP infatti commetandolo la matrice si riempie correttamente.
Il problema è che inserendo i thread e commentando l'openMP ottengo le stesse prestazioni che creando le matrici serialmente e riempiendole con l'openMP  :_doubt:
quindi vorrei poter usare i due thread che a sua volta si suddividono il ciclo for con l'openMP però non capisco a cosa si debba il riempimento della matrice errato ( alcune righe sono corrette altre tutte a 0 )
spero di essermi circa spiegato :-|


Non conosco bene OpenMP, ma il problema dovrebbe essere sempre lo stesso: thread poco robusti che ti fanno casino (ad esempio, due o più thread potrebbero riempire, erroneamente, le stessa linee, lasciandone alcune "non inizializzate" (ossia a zero se la matrice è globale).
Però, come ti dicevo, non conosco bene OpenMP, quindi potrei sbagliarmi.


bool Woman::makeYourselfBetter() {
       goto bathroom;

bathroom:
       while (1);

       return this->_isGoodResult();
}
PM