Domanda

Ho un singolo-threaded linux app che vorrei fare in parallelo. Si legge un file di dati, crea oggetti, e li inserisce in un vettore. Poi chiama un metodo di calcolo intensivo (+ 0,5 secondi) su ciascun oggetto. Voglio chiamare il metodo in parallelo con la creazione di oggetti. Mentre Ho guardato qt e TBB, io sono aperto ad altre opzioni.

Ho programmato per avviare il filo (s) mentre il vettore era vuoto. Ognuno chiamerebbe makeSolids (sotto), che ha un ciclo while che avrebbe eseguito fino interpDone == veri e tutti gli oggetti nel vettore sono stati elaborati. Tuttavia, io sono un n00b quando si tratta di threading, e ho cercato una soluzione pronta all'uso.

QtConcurrent::map(Iter begin,Iter end,function()) sembra molto facile, ma non posso usarlo su un vettore che sta cambiando in termini di dimensioni, posso? E come dovrei dirgli di aspettare per più dati?

Ho anche guardato TBB di Intel, ma sembrava che il mio thread principale sarebbe fermare se ho usato parallel_for o parallel_while. Che puzza, dal momento che il loro gestore di memoria è stato consigliato (mmgt aperta di cascata ha delle prestazioni quando multithreading).

/**intended to be called by a thread
\param start the first item to get from the vector
\param skip how many to skip over (4 for 4 threads)
*/
void g2m::makeSolids(uint start, uint incr) {
  uint curr = start;
  while ((!interpDone) || (lineVector.size() > curr)) {
    if (lineVector.size() > curr) {
      if (lineVector[curr]->isMotion()) {
        ((canonMotion*)lineVector[curr])->setSolidMode(SWEPT);
        ((canonMotion*)lineVector[curr])->computeSolid();
      }
      lineVector[curr]->setDispMode(BEST);
      lineVector[curr]->display();

      curr += incr;
    } else {
      uio::sleep(); //wait a little bit for interp
    }
  }
}

EDIT:? In sintesi, qual è il modo più semplice per elaborare un vettore, allo stesso tempo che il thread principale è che popolano il vettore

È stato utile?

Soluzione

E 'difficile dire se sei stato il pensiero su questo problema profondamente e non v'è più di quello che sta lasciando il, o se si sta pensando poco più di esso, o se sono solo diffidare di threading.

Leggere il file e la creazione degli oggetti è veloce; un metodo è lento. La dipendenza è ogni ctor consecutiva dipende dal risultato della ctor precedente - un po 'strano - ma per il resto non ci sono problemi di integrità dei dati in modo non sembra essere tutto ciò che ha bisogno di essere protetti da mutex e simili

.

Perché questo più complicato di qualcosa di simile (in pseudo-codice greggio):

while (! eof)
{
    readfile;
    object O(data);
    push_back(O);
    pthread_create(...., O, makeSolid);
}


while(x < vector.size())
{
    pthread_join();
    x++;
}

Se non si desidera ciclo sul unisce nella vostra principale poi deporre le uova fuori un filo a servirli passando un vettore di TID.

Se il numero di creato oggetti / thread è folle, utilizzare un pool di thread. O mettere un contatore è il ciclo di creazione di limitare il numero di thread che possono essere creati prima di eseguire quelle sono uniti.

Altri suggerimenti

In primo luogo, di beneficiare di threading è necessario trovare attività simile lenti per ogni thread di fare. Hai detto che il tuo trattamento per oggetto prende .5s +, quanto tempo il file di lettura / oggetto creazione introito? Si potrebbe facilmente essere un decimo o un millesimo di quel tempo, nel qual caso il vostro approccio multithreading sta per produrre beneficio realizzino e 'trascurabile. Se questo è il caso, (sì, risponderò alla tua domanda iniziale ben presto in caso non è) poi pensare contemporaneamente l'elaborazione di più oggetti. Data la tua trasformazione prende un po 'di tempo, la creazione dei thread in testa non è molto significativo, così si potrebbe semplicemente avere la vostra lettura file / oggetto thread principale la creazione di spawn un nuovo thread e dirigerla verso l'oggetto appena creato. Il filo principale quindi continua lettura / creazione di oggetti successive. Una volta che tutti gli oggetti vengono letti / ha creato, e tutti i thread di elaborazione ha lanciato, il thread principale "unisce" (aspetta) i thread di lavoro. Se questo creerà troppi thread (migliaia), poi mettere un limite su come molto più avanti il ??thread principale è consentito di ottenere: si potrebbe leggere / creare i 10 oggetti quindi unire 5, quindi leggere / creare 10, unire 10, lettura / creare 10, 10 unire ecc fino al termine.

Ora, se si vuole veramente la lettura / creare per essere in parallelo con l'elaborazione, ma l'elaborazione da serializzare, allora è ancora possibile utilizzare il metodo di cui sopra, ma unirsi dopo ogni oggetto. Questo è un po 'strano, se si sta progettando questo solo con questo approccio in mente, ma buono perché si può facilmente sperimentare con il parallelismo di elaborazione oggetto sopra pure.

In alternativa, è possibile utilizzare un approccio più complesso che coinvolge solo il thread principale (che il sistema operativo crea all'avvio del programma), e un singolo thread di lavoro che il thread principale deve iniziare. Dovrebbero essere coordinate utilizzando un mutex (variabile garantire mutuamente esclusivo, il che significa non-concorrente, l'accesso ai dati), e una variabile condizione che consente il thread di lavoro per bloccare efficacemente finché il filo principale ha fornito più lavoro. I termini - variabile mutex e condizioni -. Sono le condizioni standard del threading POSIX che usa Linux, quindi dovrebbero essere utilizzati per la spiegazione delle librerie particolari che ti interessa Sommariamente, il thread lavoratore fino a quando la lettura principale / creano filo trasmissioni esso un segnale di sveglia che indica un altro oggetto è pronto per l'elaborazione. Si consiglia di avere un contatore con indice dell'ultimo completamente creato, pronta per l'elaborazione oggetto, quindi il thread di lavoro può mantenere conte di oggetti trasformati e muoversi lungo quelle pronte prima ancora verificando la variabile di condizione.

@Caleb: abbastanza - Forse avrei dovuto sottolineato attivi le discussioni. Il filo GUI dovrebbe sempre essere considerato uno.

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