2011-07-16 30 views
6

Estoy empezando a experimentar agregando OpenMP a algunos códigos SSE.Error de segmentación con OpenMp y SSE

Mi primer programa de prueba ALGUNAS VECES se bloquea en _mm_set_ps, pero funciona cuando configuro el if (0).

Parece tan simple que me falta algo obvio. Estoy compilando con gcc -g -fopenmp -march = Core2 -pthreads

#include <stdio.h> 
    #include <stdlib.h> 
    #include <immintrin.h> 

    int main() 
    { 
    #pragma omp parallel if (1) 
    { 
    #pragma omp sections 
     { 
    #pragma omp section 
      { 
       __m128 x1 = _mm_set_ps (1.1f, 2.1f, 3.1f, 4.1f); 
      } 
    #pragma omp section 
      { 
       __m128 x2 = _mm_set_ps (1.2f, 2.2f, 3.2f, 4.2f); 
      } 
     } // end omp sections 
    } //end omp parallel 

    return 0; 
    } 

Respuesta

6

Este es un error en la implementación de openMP. Estaba teniendo el mismo problema en gcc en Windows (MinGW). -mstackrealign opción de línea de comando resolvió mi problema. Esto agrega una instrucción al prólogo de cada función para realinear la pila en el límite de 16 bytes. No noté ninguna penalización de rendimiento. También puede intentar agregar __attribute__ ((force_align_arg_pointer)) a una declaración de función, que debería hacer lo mismo, pero solo para una función específica. Puede que tenga que poner el código SSE en una función separada a la que llame desde la función con #pragma omp, para que la pila tenga la posibilidad de realinearse.

Dejé de tener el problema cuando pasé a compilar para un objetivo de 64 bits (MinGW64, como TDM GCC compilación).

Juego con las instrucciones AVX que requieren una alineación de 32 bytes, pero GCC no admite eso para Windows. Esto me obligó a corregir el código de ensamblado producido utilizando un script de python, pero funciona.

+0

El uso de -mstackrealign parece haber resuelto el problema. Y si hay una penalización de rendimiento, ¡es mejor que no tener ningún rendimiento! Veré cómo funciona con un código más complejo. Gracias por tu ayuda. Desafortunadamente, no tengo una máquina de 64 bits para jugar, con. Tengo una PC AVX, así que es una pena que gcc aún no la admita. –

+0

Para ser precisos, gcc admite AVX, incluido Core i7 2nd gen (Sandy Bridge), y de lo que leo en línea funciona muy bien en Linux. Pero he tenido muchos problemas de fallas de segmentación en Windows con MinGW64, por lo que probablemente se trate de un error relacionado con MinGW. Pero podría estar haciendo algo mal ... –

+0

La opción g ++ '-mstackrealign' funcionó perfectamente. Para la alternativa, en mi caso también tuve que agregar el atributo 'noinline' para asegurarme de que la llamada a la función estaba allí en primer lugar:' __attribute __ ((force_align_arg_pointer, noinline)) ' – phfaist

2

huelo acceso a memoria no alineada. Es la única forma en que un código como ese podría explotar (suponiendo que es el único código allí). Para que eso ocurra, los registros de XMM no se usarían, sino más bien la memoria de la pila, que solo está alineada con 4 bytes, mi suposición es que el código omp está estropeando la alineación de la pila.