2010-12-12 11 views
12

Pasar tipos alineados o estructuras con tipos alineados por valor no funciona con algunas implementaciones. Esto rompe contenedores STL, porque algunos de los métodos (como cambiar el tamaño) toman sus argumentos por valor.Tipos alineados y argumentos que pasan por valor

Ejecuto algunas pruebas con Visual Studio 2008 y no estoy del todo seguro de cuándo y cómo falla el valor de paso por paso. Mi principal preocupación es la función foo. Parece funcionar bien, pero ¿podría ser el resultado de una coincidencia o alguna otra coincidencia? ¿Qué ocurre si cambio su firma a void foo (const __m128 &)?

Su contribución es muy apreciada. Gracias.

struct A 
{ 
    __m128 x; 
    int n; 
}; 

void foo(__m128); 
void bar(A); 

void f1() 
{ 
    // won't compile 
    // std::vector<A> vec1(3); 

    // compiles, but fails at runtime when elements are accessed 
    std::vector<__m128> vec2(3); 

    // this seems to work. WHY??? 
    std::vector<__m128, some_16_byte_aligned_allocator<__m128> > vec3(3); 

    __m128 x; 
    A a; 

    // passed by value, is it OK? 
    foo(x); 

    // won't compile 
    //bar(a); 
} 

EDITAR. STL falla incluso con asignador alineado, porque el problema de pasar por valor permanece.

Encontrado este enlace pass __m128 by value

+0

¿Cuáles son los errores/advertencias de compilación que recibe? Supongo que algo así como "parámetro formal ... no estará alineado"? – celion

+0

Esto es lo que obtengo. error C2719: 'parámetro sin nombre': el parámetro formal con __declspec (alineación ('16 ')) no se alineará – watson1180

+0

En x64, los argumentos de función admiten la alineación de 16 bytes, por lo que este problema desaparece. Sé que eso no resuelve tu problema inmediato, pero bueno, es marginalmente mejor que nada. ;) – jalf

Respuesta

2

creo que la única manera segura de hacer esto en general es pasar por referencia. Algunas plataformas (por ejemplo, Xbox 360) admiten el paso de argumentos de vectores en los registros, pero no creo que esto sea posible en x86.

Para el caso std::vector, deberá asegurarse de que la memoria asignada esté alineada con 16 bytes; de lo contrario, se bloqueará cuando intente realizar la mayoría de las operaciones en vectores no alineados.

Si admite varias plataformas, un plan seguro es usar typedef, p. Ej.

typedef const MyVector& MyVectorParameter; 

A continuación, puede cambiar el typedef en plataformas que soportan vector de pasar por valor.

+0

Reemplazando la ayuda del asignador con std :: vector <__m128>, pero std :: vector aún no compila. – watson1180

+0

¿Marcó 'sizeof (A)'? Si no es un múltiplo de 16 bytes, los elementos subsiguientes de la matriz de almacenamiento asignada por el vector no se alinearán, incluso si el comienzo del almacenamiento está alineado. –

+0

En mi plataforma el tamaño de A es de 32 bytes.Una alineación incorrecta provocaría la falla del tiempo de ejecución, pero el vector no se compilará independientemente del asignador. – watson1180

1

la función de cambio de tamaño() que se utiliza con frecuencia está causando toda la alineación y tal vez usted puede intentar especializar la plantilla de vectores para __m128?

Cuestiones relacionadas