Pregunta

Estoy trabajando en un códec de video para OMAP3430. Ya tengo un código escrito en C ++, y trato de modificar / portar ciertas partes para aprovechar el DSP (el SDK (OMAP ZOOM3430 SDK) que tengo tiene un DSP adicional).

Traté de portar un pequeño bucle for que se ejecuta sobre una cantidad muy pequeña de datos (~ 250 bytes), pero alrededor de 2 millones de veces en datos diferentes. Pero la sobrecarga de la comunicación entre CPU y DSP es mucho más que la ganancia (si tengo alguna).

Supongo que esta tarea es muy similar a la optimización de un código para las GPU en las computadoras normales. Mi pregunta es ¿qué tipo de piezas serían beneficiosas? ¿Cómo se encargan los programadores de GPU de tales tareas?

editar:

  1. La aplicación GPP asigna un búfer de tamaño 0x1000 bytes.
  2. La aplicación GPP invoca DSPProcessor_ReserveMemory para reservar un espacio de dirección virtual DSP para cada búfer asignado utilizando un tamaño que es 4K mayor que el búfer asignado para tener en cuenta la alineación automática de la página. El tamaño total de la reserva también debe alinearse a lo largo de un límite de página de 4K.
  3. La aplicación GPP invoca DSPProcessor_Map para asignar cada búfer asignado a los espacios de direcciones virtuales DSP reservados en el paso anterior.
  4. La aplicación GPP prepara un mensaje para notificar a la fase de ejecución DSP de la dirección base del espacio de direcciones virtuales, que se ha asignado a un búfer asignado en el GPP. La aplicación GPP usa DSPNode_PutMessage para enviar el mensaje al DSP.
  5. GPP invoca memcpy para copiar los datos que se procesarán en la memoria compartida.
  6. La aplicación GPP invoca DSPProcessor_FlushMemory para garantizar que la caché de datos se haya vaciado.
  7. La aplicación GPP prepara un mensaje para notificar a la fase de ejecución de DSP que ha terminado de escribir en el búfer y que el DSP ahora puede acceder al búfer. El mensaje también contiene la cantidad de datos escritos en el búfer para que el DSP sepa cuántos datos copiar. El GPP usa DSPNode_PutMessage para enviar el mensaje al DSP y luego invoca DSPNode_GetMessage para esperar para escuchar un mensaje del DSP.

Después de esto, se inicia la ejecución del programa DSP, y DSP notifica al GPP con un mensaje cuando finaliza el procesamiento. Solo para intentarlo, no pongo ningún procesamiento dentro del programa DSP. Acabo de enviar un " procesamiento terminado " mensaje de vuelta al GPP. Y esto todavía consume mucho tiempo. ¿Podría ser debido al uso de memoria interna / externa, o es simplemente debido a la sobrecarga de comunicación?

¿Fue útil?

Solución 3

De las mediciones que hice, un ciclo de mensajería entre CPU y DSP toma aproximadamente 160us. No sé si esto se debe al kernel que uso o al controlador del puente; pero esto es mucho tiempo para un simple back & amp; cuarto mensaje.

Parece que solo es razonable portar un algoritmo a DSP si la carga computacional total es comparable al tiempo requerido para la mensajería; y si el algoritmo es adecuado para la computación simultánea en CPU y DSP.

Otros consejos

El OMAP3430 no tiene un DSP integrado, tiene un motor de decodificación de video / audio IVA2 + conectado al bus del sistema y el núcleo Cortex tiene instrucciones SIMD tipo DSP. La GPU del OMAP3430 es una unidad basada en PowerVR SGX. Si bien tiene sombreadores programables y no creo que haya ningún soporte para la programación de propósito general ala CUDA u OpenCL. Podría estar equivocado pero nunca he oído hablar de ese apoyo

Si está usando el motor de codificación / decodificación IVA2 + que está a bordo, debe usar las bibliotecas adecuadas para esta unidad y solo es compatible con códecs específicos de lo que sé. ¿Estás intentando escribir tu propia biblioteca en este módulo?

Si está utilizando el DSPish integrado de Cortex (instrucciones SIMD), publique algún código.

Si su placa de desarrollo tiene un DSP adicional, ¿cuál es el DSP y cómo está conectado al OMAP?

En cuanto a la pregunta de la GPU de escritorio, en el caso de la decodificación de video, utiliza las bibliotecas de funciones suministradas por el vendedor para realizar llamadas al hardware, hay varias, VDAPU para Nvidia en Linux, bibliotecas similares en Windows (PureViewHD creo que se llama ) ATI también tiene bibliotecas tanto de Linux como de Windows para sus motores de decodificación integrados, no sé los nombres.

No sé cuál es la base de tiempo en la que se transfieren los datos, pero sé que el TMS32064x que figura en la hoja de especificaciones del SDK tiene un motor DMA muy potente. (Supongo que es el MDK original ZOOM OMAP34X. Dice que tiene un 64xx.) Espero que el OMAP tenga algo simalar, úselos para su mayor ventaja. Recomendaría configurar "ping-pong" almacena el búfer en el ram interno del 64xx y usa la SDRAM como memoria compartida con el controlador de transferencias de DMA. La RAM externa será un cuello de botella en cualquiera de las piezas de la serie 6xxx, así que mantenga todo lo que pueda encerrado en la memoria interna para mejorar el rendimiento. Normalmente, estas partes tendrán la capacidad de transportar 8 palabras de 32 bits al núcleo del procesador una vez que esté en la memoria interna, pero eso varía de una parte a otra según el nivel de caché que le permite asignar como ram de acceso directo. Las partes sensibles al costo de TI mueven la "memoria mapeable" más lejos que algunas de las otras fichas. También todos los manuales de las piezas están disponibles en TI para su descarga gratuita en PDF. Incluso me dieron copias impresas gratis del manual de la CPU TMS320C6000 y del conjunto de instrucciones y muchos otros libros.

En lo que respecta a la programación, es posible que deba utilizar algunos de los "intrínsecos del procesador". o ensamblaje en línea para optimizar cualquier matemática que esté haciendo. Para el 64xx, favorezca la operación de enteros cuando sea posible porque no tiene un núcleo de coma flotante incorporado. (Esos están en la serie 67xx.) Si observa las unidades de excitación y puede mapear sus cálculos de manera que las diferentes partes apunten a diferentes operaciones de una manera que puede ocurrir en un solo ciclo, entonces podrá lograr el mejor rendimiento. de esas partes El manual del conjunto de instrucciones enumera los tipos de operaciones que realiza cada unidad de ejecución. Si puede dividir su cálculo en conjuntos de flujo de datos duales y desenrollar un poco los bucles, el compilador será "mejor". a usted cuando la optimización completa está activada. Esto se debe al hecho de que el procesador está dividido en un lado izquierdo y uno derecho con unidades de ejecución casi idénticas en ambos lados.

Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top