2011-07-03 16 views
7

Próbowałem swoich sił w optymalizacji kodu, który używam w sisie wewnętrznym microsoft. Jednym z największych problemów podczas optymalizacji mojego kodu jest LHS, który ma miejsce, gdy chcę użyć stałej. Wydaje się, że istnieją pewne informacje na temat generowania pewnych stałych (here i here - section 13.4), ale wszystkie ich zgromadzenia (których wolałbym uniknąć).Stałe pływaki z kartą SIMD

Problem polega na tym, że próbuję zaimplementować to samo z wewnętrznym, msvc narzeka na niekompatybilne typy itp. Czy ktoś wie o jakichkolwiek równoważnych sztuczkach wykorzystujących wewnętrzne elementy?

Przykład - generowanie {1.0,1.0,1.0,1.0}

//pcmpeqw xmm0,xmm0 
__m128 t = _mm_cmpeq_epi16(t, t); 

//pslld xmm0,25 
_mm_slli_epi32(t, 25); 

//psrld xmm0,2 
return _mm_srli_epi32(t, 2); 

ten wytwarza wiązkę błędów około niezgodnych typu (__m128 vs _m128i). Jestem całkiem nowy w tym, więc jestem pewien, że brakuje mi czegoś oczywistego. Czy ktoś może pomóc?

tldr - W jaki sposób mogę wygenerować __m128 vec wypełniony pojedynczą stałą precyzją z ms intrinsics?

Dziękuję za przeczytanie :)

+0

Co sprawia, że ​​myślisz, że musisz to zrobić? Zazwyczaj stałe są ładowane tylko jeden raz, przed pętlą obliczeniową, więc względny koszt dostępu do pamięci jest nieistotny. –

+0

Mam kilka stałych, z których wszystkie są używane w pętli, która niestety już wydaje się używać wszystkich rejestrów 8 x mm. Wewnątrz vnu dostaję bardzo wysoki CPI w punkcie, w którym używane są niektóre z tych stałych. Pomyślałem, że może uda mi się zmniejszyć liczbę stałych, do których uzyskuję dostęp, i wygenerować trochę, co może obniżyć koszty, ponieważ jeden ukrywa koszt drugiego. Co dziwne, użycie słowa kluczowego register na jednej ze stałych pomogło całkiem sporo (nawet jeśli spowodowało to, że zamiast tego zamiast wartości xmm wyprowadzono inną wartość). – JBeFat

+4

Użyj x86-64, jeśli możesz - w ten sposób otrzymasz 16 rejestrów XMM. Zauważ również, że nawet jeśli otrzymasz jeden lub więcej pomyłek w pamięci podręcznej za pierwszym razem, gdy te stałe zostaną załadowane, powinno to zostać zamortyzowane w dużej liczbie iteracji, gdzie stałe będą następnie w pamięci podręcznej L1. (O ile oczywiście masz tylko małą liczbę iteracji pętli?) –

Odpowiedz

3

Wystarczy rzucić __m128i do __m128 przy użyciu _mm_castsi128_ps. Również druga linia powinna być

t = _mm_slli_epi32(t, 25) 
+0

Dzięki! Miałem przeczucie, że to będzie coś prostego. – JBeFat

4
+0

'0x1a11 movaps xmm6, xmmword ptr [0x414890]' ' 0x1a18 xorps xmm5, xmm5' Cześć, dzięki za poświęcenie czasu, aby odpowiedzieć :) Jak widać z (źle sformatowane, przepraszam) Lista powyżej __mm_set_ps tak naprawdę nie pomaga mi, ponieważ wciąż używa movaps do załadowania stałych z jakiegoś miejsca w pamięci. Chciałbym użyć istniejących metod generowania stałych bezpośrednio w rejestrach xmm. – JBeFat

+0

@JBeFat: Czy próbowałeś po prostu rzucić wynik? Te triki używają instrukcji liczb całkowitych do tworzenia wartości zmiennoprzecinkowych, więc nie dziwię się, że kompilator narzeka na niezgodność typów. –

+1

Należy również pamiętać, że nie ma sklepu LHS z '__mm_set_ps', ponieważ FPU nie jest zaangażowany. –