2010-07-13 1 views
14

Questo probabilmente è stato chiesto più e più volte, ma non ho trovato nulla di utile così qui va di nuovo ...Ottimizzazione delle prestazioni OpenGL per il throughput geometria

Nella mia domanda ho bisogno di rendere un gran mesh (una un paio di milioni di triangoli o più) e sto avendo qualche problema a ottenere dei frame rate decenti. La CPU è praticamente inattiva quindi sono decisamente vincolata alla GPU. La modifica della risoluzione non influisce sulle prestazioni, quindi non è frammentata o legata al raster.

La mesh è dinamica (ma localmente statica) quindi non è possibile memorizzare l'intero elemento nella scheda video e renderlo con una chiamata. Per motivi applicativi specifici, i dati vengono memorizzati come un ottetto con voxel nelle foglie, con i mezzi che ottengo fondamentalmente gratuitamente. I dati del vertice sono costituiti da coordinate, normali e colori, senza trame o ombreggiature.

Il mio primo approccio è stato quello di eseguire il rendering di tutto dalla memoria utilizzando un grande VBO STREAM_DRAW, che si è rivelato troppo lento. Il mio pensiero iniziale era che forse stavo sovraccaricando il bus (spingendo ~ 150 MiB per fotogramma), quindi ho implementato uno schema di cache che memorizza la geometria usata di recente per rendere l'oggetto in VBO statici sulla scheda grafica, con ogni VBO che memorizza un paio di 100 KiB a un paio di dati del MiB (la memorizzazione di più per VBO offre più cache thrashing, quindi c'è un compromesso qui). L'immagine sotto è un esempio di come appaiono i dati, in cui tutto ciò che è colorato in rosso viene estratto dai VBO memorizzati nella cache.

Example of the rendered data http://gimaker.users.sourceforge.net/0010.png

Come i numeri che seguono mostrano, non vedo uno spettacolare aumento delle prestazioni quando si utilizza la cache. Per una maglia completamente statica di circa 1 milione di triangoli vengo seguenti frequenze:

  • Senza cache: 1.95 Hz
  • cache utilizzando matrici vertex: 2.0 Hz (> 75% della maglia è cache)
  • caching utilizzando STATIC_DRAW VBOs: 2.4 Hz

Così le mie domande è come faccio accelerare questo? I.e .:

  • Qual è il formato del vertice consigliato per ottenere prestazioni decenti? Utilizzo la memoria interlacciata con posizioni e normali come GL_FLOAT e GL_UNSIGNED_BYTE per i colori, con un byte di riempimento per ottenere l'allineamento di 4 byte (28 byte/totale del vertice).
  • Se sia possibile utilizzare lo stesso buffer per le normali per tutte le mie caselle (tutte le caselle sono allineate agli assi in modo da poter allocare un buffer normale della dimensione della voce della cache più grande e usarlo per tutti).
  • Come sapere quale parte della pipeline è il collo di bottiglia? Non ho una scheda video spettacolare (Intel GM965 con driver Linux open source), quindi è possibile che abbia raggiunto il limite. Quanto posso aspettarmi dal tipico hardware (grafica integrata di 2-3 anni, grafica moderna integrata, grafica moderna discreta)?
  • Eventuali altri suggerimenti su come si potrebbe affrontare questo, trappole, ecc

io non sono interessato a risposte che suggeriscono LOD (ho già provato questo), suggerimenti specifici del produttore o utilizzando le funzionalità di OpenGL da tutto ciò in seguito di 1,5.

+0

Le tue primitive sono costituite solo da riquadri allineati agli assi? – Stringer

+0

@Stringer Bell: Sì (ma non necessariamente allineato con gli assi del mondo). – Staffan

+1

Non sono sicuro, ma direi che hai raggiunto il limite della scheda grafica. Ho cercato un po 'su google e sembra che Intel GM965 abbia prestazioni piuttosto basse, soprattutto per i giochi. (Il tuo non è un gioco ma sembra abbastanza "difficile" da renderizzare). Nvidia ha una lista di quanti triangoli le loro carte possono rendere/secondo-forse puoi classificare la tua carta con questa lista per scoprire il limite "teorico". – InsertNickHere

risposta

5

Probabilmente non state andando a come questa risposta ....

ho trovato il problema: Intel GM965 con i driver Linux open source

Mentre il mio lavoro attuale non ha colpito il vostro volume di dati, abbiamo reso diversi milioni di vertici in VBO e Intel hardware/driver di grafica si sono dimostrati inutili. Prendi una scheda NVidia (e dimenticati di dover usare il driver binario, funziona solo) e sarai pronto. Non deve nemmeno essere la generazione attuale anche se un Quadro di fascia alta (se il lavoro sta pagando) o la serie GTX 400 di fascia alta (se stai pagando o stai solo cercando di risparmiare qualche soldo al lavoro) dovrebbe fare solo bene con l'ultima piloti. Si potrebbe anche provare a trovare una macchina con questo hardware da testare se l'aggiornamento della macchina non è un'opzione.

+0

Sembra che tu abbia ragione. Ho provato su una macchina con una grafica migliore, non un Quadro, ma nondimeno migliore, e ho ottenuto 15 Hz con il caching e metà senza. È più un inconveniente che un problema poiché sono solo lo sviluppatore e non (attualmente) l'utente principale di esso. – Staffan

+0

@Staffan: non significa che abbiate portato a termine il GMA 965 al massimo. Forse stai solo facendo qualcosa di male per le esibizioni. Sinceramente, prenderei in considerazione la possibilità di provare Intel Media Accelerator Profiler (se l'applicazione è portatile, naturalmente). Non dimenticare che GMA sono renderer basati su tile ... – Stringer

+0

@Stringer Bell: sembra proprio che la scheda video/i driver impostino il limite. Dopo un po 'di messa a punto del mio meccanismo di caching ottengo ~ 28 milioni di triangoli/s su un GeForce 3 Ti200, non ci sono specifiche ufficiali su quanti triangoli può spingere ma sembra che potrebbe essere ragionevolmente vicino al limite. – Staffan

0

Vorrei utilizzare prima un profiler delle prestazioni (come gDEBugger), in modo da poter capire se si dispone di vertice, frammento o bus limitato, ecc.È difficile indovinare quali ottimizzazioni eseguire in un caso del genere (Intel + driver open source).

Hai provato anche in modalità VA? Stai usando glDrawElements? glDrawArrays? I dati sono compatibili con il vertice-cache (pre e post-trasformazione)?

+0

Bell: vorrei usare un profiler OpenGL se c'era un open source (o gratuito) per Linux (vedi [la mia altra domanda] (http://stackoverflow.com/questions/3235864/open-source-opengl-profiler- for-linux)). I driver open source sono i driver ufficiali sviluppati da Intel, ma immagino che tu lo sappia già. Sto usando glDrawArrays dato che non posso condividere i dati tra i vertici (tutti i vertici hanno diverse normali o posizioni). Cos'è la modalità VA? I dati sono AFAICT di tipo cache-friendly, ovvero storage interlacciato (non sono sicuro di come le trasformazioni possano influire su questo). – Staffan

+0

Ho provato gDEBugger nonostante sia closed source e non funziona per me (mi dà un contesto indiretto e quindi causa un SIGSEGV). – Staffan

+0

La modalità VA è costituita da semplici array di vertex 1.1. Le cache di trasformazione post vengono utilizzate solo se si dispone di indici (vedere http://www.opengl.org/wiki/Post_Transform_Cache). Usi GL_QUAD o GL_TRIANGLES per il rendering delle tue scatole? – Stringer

0

Non so la tua "mesh" ma sembra che siano tutti cubi. Se è possibile per voi, eseguire il rendering di un singolo cubo unione in un elenco di visualizzazione e visualizzare una versione ridimensionata di tale elenco di visualizzazione. Ciò dà spesso un 10x di accelerazione, poiché il bus non viene pompato con i dati dei vertici o la memoria video esaurita.

Ovviamente ciò dipende dalla possibilità di modificare i dati. Potrebbe non essere il caso se davvero non è come nella foto.

+0

Sono tutti cuboidi, sì. Come ho descritto nell'OP, uso una cache con VBO per evitare di sovraccaricare il bus - nessuna chiamata glVertex3() è stata coinvolta nella generazione dell'immagine precedente. – Staffan

+0

Ma VBO! = Elenco di visualizzazione ... La differenza è che VBO utilizza ancora un GRANDE ARRAY, anche se è nella memoria video. Nella maggior parte dei casi per configurazioni del genere ottengo il massimo per un buck che chiama 10000 x un DL di 10000 cubi in un array di vertici. – rioki