Pregunta

Theres son par de lugares en mi base de código en la que la misma operación se repite un número muy grande de veces para un gran conjunto de datos. En algunos casos se toma un tiempo considerable para procesar estos.

Creo que el uso de ESS para implementar estos bucles debe mejorar significativamente su rendimiento, especialmente cuando muchas de las operaciones se llevan a cabo en el mismo conjunto de datos, por lo que una vez que los datos se leen en la memoria caché en un principio, no debería haber ningún caché pierde por estancar ella. Sin embargo no estoy seguro de ir sobre esto.

  • ¿Hay un compilador y el sistema operativo de manera independiente a escribir el código para tomar ventaja de las instrucciones SSE? Me gustan las características intrínsecas del VC ++, que incluyen operaciones de SSE, pero no he encontrado ninguna solución compilador cruzado.

  • todavía tengo que apoyar algunas CPU es que, o bien no tienen o soporte SSE limitada (por ejemplo, Intel Celeron). ¿Hay alguna manera de evitar tener que hacer diferentes versiones del programa, como tener algún tipo de "enlazador en tiempo de ejecución" que une ya sea en el básico o SSE código optimizado basado en la CPU ejecuta cuando se inicia el proceso?

  • ¿Qué pasa con otras extensiones de CPU, mirando a los conjuntos de instrucciones de diversos espectáculos de Intel y AMD CPU hay unos pocos de ellos?

¿Fue útil?

Solución

Para su segundo punto hay varias soluciones, siempre y cuando se puede separar las diferencias en diferentes funciones:

  • lisos viejos punteros de función C
  • vinculación dinámica (que generalmente depende de los punteros de función C)
  • si está utilizando C ++, que tienen diferentes clases que representan el soporte para diferentes arquitecturas y el uso de funciones virtuales pueden ayudar enormemente con esto.

Tenga en cuenta que debido a que estaría confiando en las llamadas a funciones indirectas, las funciones que resumen las diferentes operaciones por lo general necesitan para representar la funcionalidad de nivel algo más alto o puede perder lo que las ganancias que obtiene de la instrucción optimizado en la sobrecarga de llamadas (en otra las palabras no abstracta las operaciones individuales de ESS -. abstraer el trabajo que está haciendo)

Este es un ejemplo el uso de punteros de función:

typedef int (*scale_func_ptr)( int scalar, int* pData, int count);


int non_sse_scale( int scalar, int* pData, int count)
{
    // do whatever work needs done, without SSE so it'll work on older CPUs

    return 0;
}

int sse_scale( int scalar, in pData, int count)
{
    // equivalent code, but uses SSE

    return 0;
}


// at initialization

scale_func_ptr scale_func = non_sse_scale;

if (useSSE) {
    scale_func = sse_scale;
}


// now, when you want to do the work:

scale_func( 12, theData_ptr, 512);  // this will call the routine that tailored to SSE 
                                    // if the CPU supports it, otherwise calls the non-SSE
                                    // version of the function

Otros consejos

La buena lectura sobre el tema: Detener la guerra juego de instrucciones

Breve visión de conjunto: Lo sentimos, no es posible resolver el problema en forma simple y más compatible (Intel vs AMD)

.

los intrínsecos SSE trabajan con c visual ++, GCC y el compilador de Intel. No hay ningún problema con el uso de estos días.

Tenga en cuenta que siempre debe tener una versión de su código que no utiliza SSE y constantemente comprobar que en contra de su aplicación SSE.

Esto ayuda no sólo para la depuración, también es muy útil si quieres apoyar CPU o arquitecturas que no son compatibles con las versiones requeridas de la ESS.

En respuesta a su comentario:

  

Así que efectivamente, siempre y cuando no lo intento para ejecutar código en realidad no compatibles con las instrucciones que estoy bien y que podía salirse con un "si (see2Supported) {...} else {...}" conmutador de tipo?

Depende. Está bien para instrucciones SSE existan en el binario, siempre y cuando no sean ejecutados. La CPU tiene ningún problema con eso.

Sin embargo, si se habilita la compatibilidad SSE en el compilador, lo hará de intercambio más probable es que una serie de instrucciones "normales" para sus equivalentes SSE (ops escalar de punto flotante, por ejemplo), por lo que incluso trozos de su regularidad no SSE código va a explotar en una CPU que no lo soporta.

Así que lo que tendrá que hacer es más probable compilar en dos o archivos por separado, con SSE activado, y dejar que ellos contienen todas las rutinas de la ESS. A continuación, enlace que con el resto de la aplicación, que está compilado sin soporte SSE.

En lugar de la codificación manual una implementación alternativa SSE a su código escalar, le recomiendo encarecidamente que echar un vistazo a OpenCL . Es un sistema portátil, multi-plataforma de proveedor neutral para aplicaciones computacionalmente intensivas (y es altamente compatible palabra de moda!). Usted puede escribir su algoritmo en un subconjunto de C99 diseñado para operaciones de vectorizados, que es mucho más fácil que la codificación manual SSE. Y lo mejor de todo, OpenCL generará la mejor aplicación en tiempo de ejecución, ya sea para ejecutar en la GPU o en la CPU. Así que, básicamente, se obtiene el código SSE escrito para ti.

  

Theres son par de lugares en mi base de código en la que la misma operación se repite un número muy grande de veces para un gran conjunto de datos. En algunos casos se toma un tiempo considerable para procesar estos.

Su solicitud suena como la clase de problema que OpenCL está diseñado para hacer frente. Escritura de funciones alternativas en SSE, sin duda, a mejorar la velocidad de ejecución, pero es una gran cantidad de trabajo para escribir y depurar.

  

¿Hay un compilador y el sistema operativo de manera independiente a escribir el código para tomar ventaja de las instrucciones SSE? Me gustan las características intrínsecas del VC ++, que incluyen operaciones de SSE, pero no he encontrado ninguna solución compilador cruzado.

Sí. Las características intrínsecas de la ESS se han estandarizado esencialmente por Intel, por lo que las mismas funciones funcionan de la misma entre Windows, Linux y Mac (en concreto con Visual C ++ y GNU g ++).

  

todavía tengo que apoyar algunas de CPU que, o bien no tienen o soporte SSE limitada (por ejemplo, Intel Celeron). ¿Hay alguna manera de evitar tener que hacer diferentes versiones del programa, como tener algún tipo de "enlazador en tiempo de ejecución" que une ya sea en el básico o SSE código optimizado basado en la CPU ejecuta cuando se inicia el proceso?

Se puede hacer eso (por ejemplo. Mediante dlopen()) pero es una solución muy compleja. Mucho más simple sería (en C) para definir una interfaz de función y llamar a la versión apropiada de la función optimizada a través de puntero de función, o en C ++ utilizar diferentes clases de implementación, dependiendo de la CPU detectado.

Con OpenCL no es necesario hacer esto, ya que el código se genera en tiempo de ejecución para la arquitectura específica.

  

¿Qué pasa con otras extensiones de CPU, mirando a los conjuntos de instrucciones de diversos espectáculos de Intel y AMD CPU hay unos pocos de ellos?

Dentro del conjunto de instrucciones SSE, hay muchos sabores. Puede ser bastante difícil de codificar el mismo algoritmo en diferentes subgrupos de SSE cuando ciertas instrucciones no están presentes. Sugiero (al menos al principio) que elija un nivel mínimo admitido, como SSE2, y se cae de nuevo a la aplicación escalar en máquinas más antiguas.

Esta es también una situación ideal para las pruebas unitarias / regresión, lo que es muy importante para asegurarse de que sus diferentes implementaciones producen los mismos resultados. Tener un conjunto de pruebas de datos de entrada y salida de datos bien conocidos, y ejecutar los mismos datos a través de las dos versiones de la función de procesamiento. Puede que tenga que tener una prueba de precisión para el paso (es decir. La épsilon diferencia entre el resultado y la respuesta correcta es a continuación 1e6, por ejemplo). Esto será de gran ayuda en la depuración, y si se construye en alta resolución de tiempo a su marco de pruebas, se pueden comparar las mejoras en el rendimiento al mismo tiempo.

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