gcc - procesador - ¿Cómo utilizan los compiladores modernos las instrucciones mmx/3dnow/sse?
pentium mmx (5)
He estado leyendo sobre las extensiones del conjunto de instrucciones x86, y solo parecen útiles en algunas circunstancias bastante específicas (por ejemplo, HADDPD - (Horizontal-Add-Packed-Double) en SSE3). Estos requieren un determinado diseño de registro que debe configurarse deliberadamente o aparecer en la serie de instrucciones anteriores. ¿Con qué frecuencia los compiladores de propósito general como gcc realmente usan estas instrucciones (o un subconjunto de las mismas), o se utilizan principalmente en ensambladores codificados a mano? ¿Cómo detecta el compilador dónde es apropiado usar las instrucciones SIMD?
En general, pocos compiladores los utilizan. GCC y Visual Studio generalmente no pueden usar las instrucciones SIMD. Si habilita SSE como indicador de compilador, utilizará las instrucciones SSE escalares para las operaciones regulares de punto flotante, pero en general, no espere que las vectorizadas se usen automáticamente. Las versiones recientes de GCC podrían usarlas en algunos casos, pero no funcionó la última vez que lo intenté. El compilador C ++ de Intel es el único compilador grande que conozco que es capaz de auto-vectorizar algunos bucles.
En general, sin embargo, tendrás que usarlos tú mismo. Ya sea en ensamblador en bruto o mediante el uso de intrínsecos del compilador. En general, diría que los intrínsecos son el mejor enfoque, ya que permiten que el compilador entienda mejor el código, y así planificar y optimizar, pero en la práctica, sé que MSVC al menos no siempre genera un código muy eficiente a partir de intrínsecos, Así que el simple asm puede ser la mejor solución. Experimenta, ve lo que funciona. Pero no espere que el compilador utilice estas instrucciones por usted, a menos que 1) use el compilador correcto y 2) escriba bucles bastante simples que se puedan vectorizar de forma trivial.
Actualización 2012
Ok, han pasado tres años desde que escribí esta respuesta. GCC ha podido auto-vectorizar (simple) el código por un par de años, y en VS2012, MSVC finalmente obtiene la misma capacidad. Por supuesto, la parte principal de mi respuesta todavía se aplica: los compiladores aún pueden solo vectorizar el código bastante trivial. Para algo más complejo, estás atrapado jugando con intrínsecos o asm en línea.
La cuestión de cómo explotar SSE y otras unidades vectoriales pequeñas automáticamente (sin la dirección del programador en forma de construcciones de lenguaje especiales o compiladores "intrínsecos" especialmente bendecidos) ha sido un tema de investigación del compilador durante algún tiempo. La mayoría de los resultados parecen estar especializados para un dominio de problemas particular, como el procesamiento de señales digitales . No he mantenido la literatura sobre este tema, pero lo que he leído sugiere que explotar la unidad de vectores (SSE) sigue siendo un tema de investigación, y que uno debería tener bajas expectativas de compiladores de propósito general que se usan comúnmente en el campo. .
Término de búsqueda sugerido: vectorizing compiler
Mono puede usar extensiones SIMD siempre y cuando uses sus clases para vectores. Puedes leer sobre esto aquí: http://tirania.org/blog/archive/2008/Nov-03.html
GCC debería realizar una vectorización automática siempre que esté usando -O3
o una marca específica. Tienen una página de información aquí: http://gcc.gnu.org/projects/tree-ssa/vectorization.html
Probablemente no los usaría si pudiera. Cuidado con las incompatibilidades de Intel / AMD. Esto puede ser un consejo obsoleto ahora, o puede que no. No tengo manera de decirlo.
EDIT: obsoleto, probablemente por un tiempo muy largo.
Si usa el compilador vector pascal obtendrá un código SIMD eficiente para los tipos para los cuales SIMD le da una ventaja. Básicamente esto es algo de longitud inferior a 64 bits. (Para reales de 64 bits, en realidad es más lento hacer SIMD). Las últimas versiones del compilador también se paralizarán automáticamente a través de los núcleos