Mejore la productividad y potencie el rendimiento de C++

Presentación de Intel SIMD Data Layout Template (Intel SDLT) para potenciar la eficiencia del código C++ vectorizado

Intel suministra muchas de las herramientas que ayudan a detectar los “puntos calientes” del código (por ejemplo, Intel VTune Amplifier XE) y ofrecen sugerencias sobre cómo optimizarlo (por ejemplo, Intel Advisor XE). El compilador de C++ de Intel genera informes de optimización detallados que le pueden indicar si la vectorización de un bucle específico en C++ fue exitosa. Intel está introduciendo ahora una nueva librería de plantillas incluida en el compilador C++ de Intel, que forma parte de Intel Parallel Studio XE e Intel System Studio. Si es usted un desarrollador de aplicaciones que utiliza C++, sabe que optimizar manualmente la disposición de los accesos a memoria es una tarea que requiere un esfuerzo considerable. La librería Intel SIMD Data Layout Template (Intel SDLT) optimiza el código C++ permitiendo al programador cambiar de una representación de array de estructuras (Array of Structures, AOS) a una representación de estructura de arrays (Structure of Arrays, SOA) con un esfuerzo y sobrecarga mínimas. La representación SOA mejora la utilización de la memoria y facilita la vectorización, evitando la conversión de representaciones de estructuras de datos.

Los más recientes procesadores y coprocesadores de Intel ofrecen instrucciones vectoriales vector y soporte para el modelo única instrucción/múltiples datos (SIMD). Mediante las instrucciones Intel Advanced Vector Extensions 512 (Intel AVX-512), el código vectorizado es teóricamente capaz de ofrecer un rendimiento 8 veces superior de las operaciones de punto flotante de doble precisión (o 16 veces en precisión simple) en comparación con el rendimiento del código no vectorizado. Desafortunadamente, ese límite teórico es rara vez alcanzado, especialmente en el caso de código heredado que no fue desarrollado pensando en la vectorización. Sin atacar el problema de la disposición de los datos en memoria, se termina dejando una buena parte de las mejoras de rendimiento encima de la mesa.

En C++, la elección de cómo disponer lo datos en memoria es crucial para alcanzar una vectorización eficiente. Esto es especialmente cierto cuando se trabaja con estructuras y arrays. Es común para los desarrolladores representar un array utilizando un contenedor de la librería estándar de plantillas (STL) de C++ como std::vector.

Aunque tal disposición de los datos podría parecer natural a un programador de C++, la sobrecarga que provoca cargar este conjunto de datos AOS en los registros vectoriales negaría las ventajas de rendimiento proporcionadas por la vectorización. Convertir la representación AOS en una representación SOA sería positivo para la vectorización, pero no es nada intuitivo para el programador de C++.

Aquí es donde entra a jugar su papel Intel SDLT.

La librería SDLT suministra una interfaz AOS al usuario, pero almacena los datos en formato SOA en memoria. Esto abstrae el problema de la disposición de datos orientada a SIMD del programador. Intel SDLT ofrece una interfaz de alto nivel utilizando características estándar de ISO C++11 y no necesita ningún soporte especial del compilador para trabajar. Gracias a su disposición optimizada para SIMD, es capaz de aprovechar mejor características de rendimiento del compilador de Intel como las extensiones SIMD de OpenMP e Intel Cilk Plus.

Para usar la librería, usted deberá declarar sus tipos de datos como primitivas, describiéndolos para SDLT. Entonces podrá utilizar sus primitivas con los contenedores SDLT genéricos (en vez de std::vector). Utilice los métodos de acceso a datos del contenedor en vez de punteros a array o iteradores. Cuando son utilizados con un modelo de programación vectorial explícito, los métodos de acceso de los contenedores de Intel SDLT gestionan la transformación de datos y permiten al compilador generar código SIMD eficiente.

Cunado un método de acceso es utilizado con el índice del bucle para exportar a o importar de una variable local (dentro del cuerpo del bucle), el vectorizador del compilador puede acceder de manera transparente al formato de datos orientado a SIMD y, cuando sea posible, realizar cargas múltiples. En muchos casos, el compilador puede optimizar su representación privada de objetos locales dentro del bucle para que sean SOA. En el ejemplo anterior, como tanto la disposición subyacente de la memoria del contenedor como la representación privada del compilador de los objetos locales es SOA, el compilador puede generar cargas múltiples eficientes.

Representar los datos en memoria en formato SOA permite al compilador cargar directamente los elementos de arrays a los registros vectoriales. Esto ayuda enormemente a la vectorización SIMD a alcanzar todo su potencial. En contraste, operar directamente sobre representaciones AOS puede requerir instrucciones adicionales para poblar los registros vectoriales, consumiendo espacios de ejecución sin contribuir resultados.

En resumen, usted puede aprovechar SDLT para incrementar su productividad, dejando que éste se preocupe de la disposición óptima de la memoria, así como para incrementar el rendimiento de su código C++ listo para SIMD, como muestra la siguiente tabla.

Incremente la productividad de los desarrolladores que usan C++En lugar de dejar de usar objetos C++ y volver a arrays de C al implementar código SIMD, utilice contenedores genéricos con un mínimo esfuerzo. Deje a SDLT realizar las transformaciones de representación por usted.
Mejore el rendimientoHaciendo contiguos los accesos a memoria, el compilador podrá generar código SIMD más eficiente y, en algunos casos, utilizar la vectorización donde la sobrecarga era antes muy alta.
Integre de manera sencillaLos contenedores SDLT ofrecen una interfaz similar a std::vector. Los métodos de acceso a datos son compatibles con los modelos de programación vectorial de Intel y encajan perfectamente con otras librerías de rendimiento de Intel.

El problema de la transformación AOS- OA ha sido ampliamente estudiado. Y SDLT ya ha Ganado una considerable popularidad en muchas industrias. Por ejemplo, DreamWorks Animation tiene una librería matemática desarrollada utilizando los principios estándar de C++ (o sea, sin pensar en la vectorización explícita). Sería complejo y poco natural cambiar manualmente la disposición de las estructuras de datos a SOA a tan gran escala. Esta era una enorme barrera a la utilización de SIMD, dado que la librería matemática se utiliza en prácticamente todas las áreas de la animación. Una vez refactorizado con SDLT, el código existente continuó compilando (in cambios) y los bucles se pudieron entonces vectorizar, con grandes beneficios.

“Utilizamos SDLT para vectorizar el código de deformación en Premo, la herramienta interna de animación utilizada en DreamWorks Animation. Las mejoras de rendimiento que se obtuvieron fueron dramáticas, y esas mejoras se tradujeron directamente en personajes de más alta calidad que podrán verse en futuras películas. Además, la propia librería fue fácil de usar e integrar en nuestra base de código existente”.

Martin Watt, DreamWorks Animation

0 comentarios

Dejar un comentario

¿Quieres unirte a la conversación?
¡Siéntete libre de contribuir!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *