Sto provando a utilizzare la parallelizzazione per migliorare la frequenza di aggiornamento per disegnare una scena 3D con oggetti ordinati gerarchicamente. L'algoritmo di disegno della scena attraversa prima in modo ricorsivo l'albero degli oggetti, e da ciò costruisce una serie ordinata di dati essenziali necessari per disegnare la scena. Quindi attraversa quell'array più volte per disegnare oggetti/sovrapposizioni, ecc. Poiché da quello che ho letto OpenGL non è un'API thread-safe, presumo che il codice di attraversamento/disegno dell'array debba essere fatto sul thread principale, ma io Sto pensando che potrei essere in grado di parallelizzare la funzione ricorsiva che riempie l'array. Il problema è che l'array deve essere popolato nell'ordine in cui gli oggetti si verificano nella scena, quindi tutte le funzionalità che associano un determinato oggetto con un indice di matrice devono essere eseguite nell'ordine corretto, ma una volta che l'indice dell'array è stato assegnato, Posso riempire i dati di quell'elemento dell'array (che non è necessariamente un'operazione banale) usando i thread worker. Quindi ecco lo pseudo-codice che sto cercando di ottenere. Spero che tu abbia l'idea della sintassi del thread xml-ish.Parallelizzazione OpenMP su una funzione ricorsiva
recursivepopulatearray(theobject)
{
<main thread>
for each child of theobject
{
assign array index
<child thread(s)>
populate array element for child object
</child thread(s)>
recursivepopulatearray(childobject)
}
</main thread>
}
Quindi, è possibile farlo utilizzando OpenMP e, in caso affermativo, come? Ci sono altre librerie di parallelizzazione che gestiscono meglio questo?
Addendum: In risposta a Davide's request for more clarification, vorrei spiegarmi un po 'più in dettaglio. Diciamo che la scena è ordinato in questo modo:
-Bicycle Frame
- Handle Bars
- Front Wheel
- Back Wheel
-Car Frame
- Front Left Wheel
- Front Right Wheel
- Back Left Wheel
- Back Right Wheel
Ora, ognuno di questi oggetti ha un sacco di dati ad esso associati, vale a dire i parametri di posizione, rotazione, dimensioni, disegno diverso, ecc Inoltre, ho bisogno di fare più passaggi su questa scena per disegnarlo correttamente. Un passaggio disegna le forme degli oggetti, un altro passaggio disegna il testo che descrive gli oggetti, un altro passaggio disegna connessioni/associazioni tra gli oggetti se ce ne sono. In ogni caso, ottenere tutti i dati di disegno da questi diversi oggetti è piuttosto lento se devo accedervi più volte, quindi ho deciso di utilizzare un passaggio per memorizzare tutti i dati in una matrice unidimensionale, e quindi tutti i dati effettivi il disegno passa solo guardando l'array. Il problema è che, poiché ho bisogno di fare push/pop OpenGL nell'ordine corretto, l'array deve essere nell'ordine di ricerca profondità-primo appropriato che è rappresentativo della gerarchia dell'albero. Nell'esempio sopra, la matrice deve essere ordinato come segue:
index 0: Bicycle Frame
index 1: Handle Bars
index 2: Front Wheel
index 3: Back Wheel
index 4: Car Frame
index 5: Front Left Wheel
index 6: Front Right Wheel
index 7: Back Left Wheel
index 8: Back Right Wheel
Quindi, l'ordinamento della matrice deve essere serializzata correttamente, ma una volta che ho assegnato quello ordinare correttamente, posso parallelizzare il riempimento della matrice. Ad esempio, dopo aver assegnato Frame bicicletta all'indice 0 e Handle Bars all'indice 1, un thread può occupare il riempimento dell'elemento array per il Bicycle Frame, mentre un altro prende il riempimento dell'elemento array per Handle Bars.
OK, penso che nel chiarire questo, ho risposto alla mia stessa domanda, quindi grazie Davide. Quindi ho pubblicato il mio answer.
Quanto sei sicuro che la costruzione dell'elenco richiede molto tempo rispetto al rendering effettivo? Hai detto a te stesso che il rendering richiede più passaggi sull'array, mentre lo sviluppo richiede solo uno. –
Greg, Sì, mi chiedo anche se il vantaggio sarà comunque marginale. Penso che dipenda anche dall'hardware su cui verrà eseguito il codice. Ma una volta entrati nei passaggi di disegno effettivi, sono per lo più un sacco di chiamate OpenGL, e dal momento che OpenGL deve stare su un thread, molta della velocità sarà limitata dalla velocità con cui la gpu può spingere il materiale del disegno. Quindi sì, il vantaggio può essere marginale, ma poiché questa è la parte principale che dipende dalla CPU, è quella che sto cercando per la parallelizzazione. In alcuni test iniziali, sembra che circa il 20-30% sia la parte della CPU/popolazione. –
Sì, dovresti pubblicare la tua risposta come "risposta ufficiale" ed eventualmente accettarla (non otterrai la reputazione, però) – Davide