2010-04-11 13 views
10

Jest to szczególnie związane z kodowaniem ARM Neon SIMD. Korzystam z instrinetyki ARM Neon dla określonego modułu w dekoderze wideo. Mam wektoryzowane dane w następujący sposób:Jak zmienić kolejność danych wektorowych za pomocą elementów wewnętrznych ARM Neon?

Istnieją cztery elementy 32-bitowe w rejestrze Neon - powiedzmy, Q0 - które ma rozmiar 128-bitowy.

3B 3A 1B 1A 

Istnieją jeszcze cztery, 32-bitowe elementy w innym rejestrze Neonów, powiedzmy Q1 o rozmiarze 128 bitów.

3D 3C 1D 1C 

Chcę ostateczne dane się być w porządku, jak pokazano poniżej:

1D 1C 1B 1A 
3D 3C 3B 3A 

Co Neon instrinsics może osiągnąć pożądaną kolejność danych?

+0

Typo w ostatecznej kolejności danych? Powinien być "3D 3C 3B 3A"? –

+0

@Paul R: Dzięki, poprawiłem to. – goldenmean

Odpowiedz

9

jak o coś takiego:

int32x4_t q0, q1; 

    /* split into 64 bit vectors */ 
    int32x2_t q0_hi = vget_high_s32 (q0); 
    int32x2_t q1_hi = vget_high_s32 (q1); 
    int32x2_t q0_lo = vget_low_s32 (q0); 
    int32x2_t q1_lo = vget_low_s32 (q1); 

    /* recombine into 128 bit vectors */ 
    q0 = vcombine_s32 (q0_lo, q1_lo); 
    q1 = vcombine_s32 (q0_hi, q1_hi); 

W teorii powinno to skompilować do zaledwie dwie instrukcje move bo vget_high i vget_low tylko reinterpretacji 128 bitowe rejestry Q w dwóch rejestrach 64 bitowy. vcombine otoh kompiluje się do jednego lub dwóch ruchów (zależy od alokacji rejestru).

Och - a kolejność liczb całkowitych na wyjściu może być dokładnie zła. Jeśli tak, po prostu zamień argumenty na vcombine_s32.

3

Wygląda na to, że powinieneś móc użyć do tego instrukcji VTRN (np. vtrnq_u32).

+0

@Paul: vtrnq_u32 nie pomaga. Właściwie potrzebuję zrobić coś takiego jak VTRN.64, ale niestety nie ma instrukcji/wewnętrznego jak VTRN.64. – goldenmean

+0

@goldenmean: przepraszam - widzę, co masz na myśli teraz - NEON wydaje się brakować ogólnych operacji permutacji/shuffle. –

+0

Link jest wyłączony ... – Antonio

4

Pamiętaj, że każdy rejestr q składa się z dwóch rejestrów d, na przykład niska część q0 to d0, a wysoka część d1. Tak więc, ta operacja to po prostu zamiana d0 i d3 (lub d1 i d2, nie jest to całkowicie jasne z twojej prezentacji danych). Istnieje nawet instrukcja wymiany, aby wykonać to w jednej instrukcji!

Nota prawna: Nie znam Neon intrinsics (bezpośrednio koduję w zestawie), choć byłbym zaskoczony, gdyby nie można było tego zrobić przy użyciu specyfikacji wewnętrznych.

2

Pierre ma rację.

vswp d0, d3

które to zrobi.

@Pierre: Przeczytałem post o NEONie na Twoim blogu kilka miesięcy temu. Byłem mile zaskoczony, że był ktoś taki jak ja - pisząc ręcznie zoptymalizowane kody montażowe, zarówno ARM, jak i NEON. Miło cię widzieć.