Domanda

Sto lavorando a un codec video per OMAP3430. Ho già un codice scritto in C ++ e provo a modificarne / portarne alcune parti per sfruttare il DSP (l'SDK (OMAP ZOOM3430 SDK) che ho un DSP aggiuntivo).

Ho provato a eseguire il porting di un piccolo ciclo for che funziona su una quantità molto piccola di dati (~ 250 byte), ma circa 2 milioni di volte su dati diversi. Ma il sovraccarico della comunicazione tra CPU e DSP è molto più del guadagno (se ne ho).

Presumo che questo compito sia molto simile all'ottimizzazione di un codice per la GPU nei normali computer. La mia domanda è il porting che tipo di parti sarebbe utile? In che modo i programmatori GPU si occupano di tali compiti?

modifica:

  1. L'applicazione GPP alloca un buffer di dimensioni 0x1000 byte.
  2. L'applicazione GPP richiama DSPProcessor_ReserveMemory per riservare uno spazio di indirizzi virtuali DSP per ciascun buffer allocato utilizzando una dimensione 4K maggiore del buffer allocato per tenere conto dell'allineamento automatico della pagina. Anche la dimensione totale della prenotazione deve essere allineata lungo un limite di pagina 4K.
  3. L'applicazione GPP richiama DSPProcessor_Map per mappare ciascun buffer allocato agli spazi degli indirizzi virtuali DSP riservati nel passaggio precedente.
  4. L'applicazione GPP prepara un messaggio per notificare alla fase di esecuzione DSP l'indirizzo di base dello spazio di indirizzi virtuale, che sono stati mappati su un buffer allocato sul GPP. L'applicazione GPP utilizza DSPNode_PutMessage per inviare il messaggio al DSP.
  5. GPP invoca memcpy per copiare i dati da elaborare nella memoria condivisa.
  6. L'applicazione GPP richiama DSPProcessor_FlushMemory per garantire che la cache dei dati sia stata svuotata.
  7. L'applicazione GPP prepara un messaggio per avvisare la fase di esecuzione del DSP che ha finito di scrivere sul buffer e il DSP ora può accedere al buffer. Il messaggio contiene anche la quantità di dati scritti nel buffer in modo che il DSP sappia quanti dati copiare. Il GPP utilizza DSPNode_PutMessage per inviare il messaggio al DSP e quindi richiama DSPNode_GetMessage in attesa di ricevere un messaggio dal DSP.

Dopodiché inizia l'esecuzione del programma DSP e DSP avvisa il GPP con un messaggio quando termina l'elaborazione. Solo per provare non inserisco alcuna elaborazione all'interno del programma DSP. Ho appena inviato una "elaborazione terminata" messaggio di ritorno al GPP. E questo richiede ancora molto tempo. Potrebbe essere a causa dell'utilizzo della memoria interna / esterna o semplicemente per il sovraccarico della comunicazione?

È stato utile?

Soluzione 3

Dalle misurazioni che ho fatto, un ciclo di messaggistica tra CPU e DSP richiede circa 160us. Non so se ciò sia dovuto al kernel che utilizzo o al bridge driver; ma questo è un tempo molto lungo per un semplice back & amp; quarta messaggistica.

Sembra ragionevole trasferire un algoritmo su DSP solo se il carico computazionale totale è paragonabile al tempo richiesto per la messaggistica; e se l'algoritmo è adatto per l'elaborazione simultanea su CPU e DSP.

Altri suggerimenti

L'OMAP3430 non ha un DSP a bordo, ha un motore di decodifica Video / Audio IVA2 + agganciato al bus di sistema e il core Cortex ha istruzioni SIMD simili a DSP. La GPU sull'OMAP3430 è un'unità basata su PowerVR SGX. Mentre ha shader programmabili e non credo che ci sia alcun supporto per la programmazione per scopi generali come CUDA o OpenCL. Potrei sbagliarmi ma non ho mai sentito parlare di tale supporto

Se si utilizza il motore di codifica / decodifica IVA2 + che è a bordo, è necessario utilizzare le librerie appropriate per questa unità e supporta solo codec specifici che conosco. Stai cercando di scrivere la tua libreria su questo modulo?

Se stai usando il DSPish incorporato di Cortex (istruzioni SIMD), pubblica un po 'di codice.

Se la tua scheda di sviluppo ha un DSP in più, qual è il DSP e come è collegato all'OMAP?

Per quanto riguarda la domanda sulla GPU desktop, nel caso della decodifica video usi le librerie di funzioni fornite dal venditore per effettuare chiamate all'hardware, ce ne sono diverse, VDAPU per Nvidia su Linux, librerie simili su Windows (penso che PureViewHD si chiami ). ATI ha anche librerie Linux e Windows per i loro motori di decodifica integrati, non conosco i nomi.

Non so quale sia la base dei tempi di trasferimento dei dati, ma so che il TMS32064x che è elencato nel foglio delle specifiche per l'SDK ha un motore DMA molto potente. (Suppongo che sia l'originale ZOOM OMAP34X MDK. Dice che ha un 64xx.) Spero che l'OMAP abbia qualcosa di simile, usali al massimo vantaggio. Consiglierei di impostare "ping-pong" buffer nel ram interal del 64xx e utilizzo della SDRAM come memoria condivisa con l'handle dei trasferimenti da parte di DMA. La RAM esterna costituirà un collo di bottiglia in qualsiasi parte della serie 6xxx, quindi mantieni tutto ciò che puoi bloccare nella memoria interna per migliorare le prestazioni. In genere, queste parti avranno la capacità di bus 8 parole a 32 bit al core del processore una volta che è nella memoria interna, ma che variano da parte a parte in base al livello di cache che consente di mappare come ram di accesso diretto. Le parti sensibili ai costi di TI spostano la "memoria mappabile" più lontano di alcuni degli altri chip. Inoltre, tutti i manuali delle parti sono disponibili da TI per il download gratuito in PDF. Mi hanno persino dato copie cartacee gratuitamente del manuale della CPU TMS320C6000 e del set di istruzioni e di molti altri libri.

Per quanto riguarda la programmazione, potrebbe essere necessario utilizzare alcuni dei "intrinseci del processore" o inline assembly per ottimizzare qualsiasi matematica che stai facendo. Per quanto riguarda il 64xx, favorire l'operazione intera quando possibile perché non ha un core in virgola mobile incorporato. (Quelli sono nella serie 67xx.) Se osservi le unità di escissione e puoi mappare i tuoi calcoli in modo tale che le diverse parti siano indirizzate a diverse operazioni in un modo che può avvenire in un singolo ciclo, sarai in grado di ottenere le migliori prestazioni di quelle parti. Il manuale del set di istruzioni elenca i tipi di operazioni eseguite da ciascuna unità di esecuzione. Se riesci a interrompere il calcolo in un doppio set di flussi di dati e a sciogliere un po 'i loop, il compilatore sarà "più bello". a te quando è attiva la piena ottimizzazione. Ciò è dovuto al fatto che il processore è suddiviso in un lato sinistro e uno destro con unità di esecuzione quasi identiche su entrambi i lati.

Spero che questo aiuti.

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