2014-04-04 10 views
5

czytałem this on MSDN, i mówiDlaczego nie należy uzyskiwać bezpośredniego dostępu do pól __m128i?

Nie należy korzystać bezpośrednio z pola __m128i. Możesz jednak zobaczyć te typy w debugerze. Zmienna typu __m128i mapuje do rejestrów XMM [0-7].

Jednak nie wyjaśnia, dlaczego. Dlaczego to jest? Na przykład, jest następujący „złe”:

void func(unsigned short x, unsigned short y) 
{ 
    __m128i a; 
    a.m128i_i64[0] = x; 

    __m128i b; 
    b.m128i_i64[0] = y; 

    // Now do something with a and b ... 
} 

Zamiast robić przypisania jak w powyższym przykładzie, należy użyć jakiegoś load funkcji?

+2

Pola są specyficzne dla firmy Microsoft. Oczywiście, nie przejmują się tym, ponieważ będą chcieli zablokować cię w swoim kompilatorze. Prawdziwy powód to wydajność. Nie ma skutecznego sposobu dostępu do poszczególnych elementów rejestru SSE. SSE4.1 ma instrukcje, aby to zrobić, ale indeks musi być stałą czasu kompilacji. – Mysticial

Odpowiedz

6

Dziedzina m128i_i64 i rodzina to rozszerzenia specyficzne dla kompilatora firmy Microsoft. Nie istnieją w większości innych kompilatorów.

Niemniej jednak są przydatne do testowania.


Prawdziwym powodem unikania ich użycia jest wydajność. Sprzęt nie może efektywnie uzyskać dostępu do poszczególnych elementów wektora SIMD.

  • Brak instrukcji pozwalających na bezpośredni dostęp do poszczególnych elementów. (SSE4.1 ma, ale wymaga stałego indeksu kompilacji).
  • Przechodzenie przez pamięć może spowodować bardzo dużą karę z powodu awarii store forwarding.

AVX i AVX2 nie rozszerzają instrukcji SSE4.1, aby umożliwić dostęp do elementów w 256-bitowym wektorze. I o ile mogę powiedzieć, AVX512 nie będzie go miał dla 512-bitowych wektorów.

Podobnie zestaw nieodłączny (na przykład _mm256_set_pd()) cierpi na ten sam problem. Są one implementowane jako seria operacji losowania danych. Lub przechodząc przez pamięć i przejmując stoiska ze sprzętem do przechowywania.


Które nasuwa się pytanie: Czy istnieje skuteczny sposób, aby wypełnić wektor SIMD z skalarnych komponentów? (lub oddzielić wektor SIMD na składniki skalarne)

Krótka odpowiedź: Niezupełnie. Kiedy używasz SIMD, oczekuje się, że wykonasz dużo pracy w wektorze. Więc narzut inicjalizacji nie powinien mieć znaczenia.

+0

Dobrze jest zobaczyć odpowiedź ponownie Mystical na SIMD. Link do wiki na temat przekazywania do sklepu jest interesujący. –

+0

Tak. Przechowywanie sklepów to bardzo duża szansa na nowoczesne procesory. Bez tego zapłacisz 20+ kar za cykl za czytanie po napisaniu. Niestety, zwykle kończy się niepowodzeniem, gdy próbujesz odczytać pamięć przy użyciu innego rozmiaru, do którego została zapisana. Nowsze procesory są lepsze, ponieważ można je czytać, o ile są całkowicie zawarte w oczekiwaniu na pisanie. Ale ustawianie wewnętrzne idzie w drugą stronę. Jednostki sklepowe nie są obecnie w stanie połączyć mniejsze sklepy w duże, dzięki czemu można je przesłać do większego ładunku. – Mysticial

+0

Dzięki!A więc w moim przykładzie kodu, jak załadować argumenty do typów __m128i? Z innych pytań mogę zobaczyć, jak to zrobić z tablicami. Jednak ładowanie tylko prostej liczby całkowitej wydaje mi się naruszeniem dostępu. Prawdopodobnie jest to problem wyrównania, ale nie jestem pewien, jak to naprawić w sposób inny niż MS ... – Gideon

Powiązane problemy