2012-06-20 35 views
16

Me gustaría combinar dos valores __m128 en uno __m256.¿Cómo combinar dos valores __m128 en __m256?

Algo como esto:

__m128 a = _mm_set_ps(1, 2, 3, 4); 
__m128 b = _mm_set_ps(5, 6, 7, 8); 

a algo como:

__m256 c = { 1, 2, 3, 4, 5, 6, 7, 8 }; 

¿existen características intrínsecas que puedo utilizar para hacer esto?

Respuesta

21

Esto debería hacer lo que quiera:

__m128 a = _mm_set_ps(1,2,3,4); 
__m128 b = _mm_set_ps(5,6,7,8); 

__m256 c = _mm256_castps128_ps256(a); 
c = _mm256_insertf128_ps(c,b,1); 

Si se invierte el orden de lo que quiere, entonces simplemente cambiar a y b.


El intrínseca de interés es _mm256_insertf128_ps que le permitirá insertar un 128-bit de registro en cualquiera inferior o mitad superior de una de 256 bits AVX registro:

http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/intref_cls/common/intref_avx_insertf128_ps.htm

La familia completa de ellos está aquí:

+1

Algunas versiones de Visual Studio (definitivamente 2010, posiblemente algunas más tarde también) tienen un error en el manejo de _mm256_castps128_ps256, por lo que es probable que este código se cuelgue en ellas. Consulte http://connect.microsoft.com/VisualStudio/feedback/details/653771/mm256-castps128-ps256-does-unaligned-read. Si necesita que su código funcione en esos compiladores, deberá usar la solución provista por el usuario1584773 que lo reemplaza con un inserto. – peastman

+0

Tenga en cuenta que esto da como resultado '__m256 {4, 3, 2, 1, 8, 7, 6, 5}' en lugar de '__m256 {1, 2, 3, 4, 5, 6, 7, 8}'. Creo que el OP quería usar '_mm_setr_ps' en lugar de' _mm_set_ps'. – plasmacel

3

Incluso esto se trabajará:

__m128 a = _mm_set_ps(1,2,3,4); 
__m128 b = _mm_set_ps(5,6,7,8); 

__m256 c = _mm256_insertf128_ps(c,a,0); 
c = _mm256_insertf128_ps(c,b,1); 

obtendrá una advertencia como c no se ha inicializado pero se puede ignorar, y si usted está buscando para las actuaciones esta solución use menos ciclo de reloj que el otro.

+1

¿Estás seguro de que esto es más rápido que la solución propuesta por Mystical? Por lo que sé, castps128_ps256 es gratis, ¿no? Además, mi aplicación se beneficia enormemente del uso del yeso en lugar del inserto (lo mismo ocurre con el extracto). – user1829358

2

También puede utilizar permute intrínseca:

__m128 a = _mm_set_ps(1,2,3,4); 
__m128 b = _mm_set_ps(5,6,7,8); 
__m256 c = _mm256_permute2f128_ps(_mm256_castps128_ps256(a), _mm256_castps128_ps256(b), 0x20); 

no sé qué camino es más rápido.