2012-06-20 14 views
16

Chciałbym połączyć dwie wartości __m128 z jedną __m256.Jak połączyć dwie wartości __m128 do __m256?

coś takiego:

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

aby coś takiego:

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

są jakieś intrinsics że mogę użyć, aby to zrobić?

Odpowiedz

21

ten powinien robić to, co chcesz:

__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); 

Jeśli kolejność jest odwrotna od tego, co chcesz, a potem po prostu przełączyć a i b.


Wewnętrzna zainteresowania jest _mm256_insertf128_ps który pozwoli Ci wstawić 128-bitowy zarejestrować się albo niższy lub górnej połowy 256-bitowym AVX rejestru:

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

Cała rodzina im jest tutaj:

+1

Niektóre wersje Visual Studio (zdecydowanie w 2010 r., Być może także niektóre później) mają błąd w obsłudze _mm256_castps128_ps256, więc ten kod prawdopodobnie ulegnie awarii. Zobacz http://connect.microsoft.com/VisualStudio/feedback/details/653771/mm256-castps128-ps256-does-unaligned-read. Jeśli potrzebujesz kodu do pracy z tymi kompilatorami, będziesz musiał użyć rozwiązania dostarczonego przez user1584773, które zastąpi je wstawką. – peastman

+0

Należy zauważyć, że powoduje to '__m256 {4, 3, 2, 1, 8, 7, 6, 5}' zamiast '__m256 {1, 2, 3, 4, 5, 6, 7, 8}'. Myślę, że OP chciał użyć '_mm_setr_ps' zamiast' _mm_set_ps'. – plasmacel

3

Nawet ten jeden będzie działać:

__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); 

Dostaniesz ostrzeżenie jako c nie jest inicjowany, ale można go ignorować, a jeśli szukasz występów To rozwiązanie użyj mniej zegara, niż drugi.

+1

Czy jesteś pewien, że jest to szybsze rozwiązanie niż proponowane przeze mnie rozwiązanie Mystical? O ile mi wiadomo, castps128_ps256 jest darmowy, prawda? Co więcej, moja aplikacja znacznie korzysta z używania rzutu zamiast wstawki (to samo dotyczy ekstraktu). – user1829358

2

mogą również korzystać permute wewnętrzna:

__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); 

Nie wiem, w jaki sposób jest szybszy.

Powiązane problemy