To pytanie jest kontynuacją mojego pytania tutaj (za radą Mistycznego):
Kontynuując moje pytanie, kiedy używam instrukcji spakowanych zamiast instrukcji skalarnych, kod używający funkcji wewnętrznych wyglądałby bardzo podobnie:
for(int i=0; i<size; i+=16) {
y1 = _mm_load_ps(output[i]);
…
y4 = _mm_load_ps(output[i+12]);
for(k=0; k<ksize; k++){
for(l=0; l<ksize; l++){
w = _mm_set_ps1(weight[i+k+l]);
x1 = _mm_load_ps(input[i+k+l]);
y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1));
…
x4 = _mm_load_ps(input[i+k+l+12]);
y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4));
}
}
_mm_store_ps(&output[i],y1);
…
_mm_store_ps(&output[i+12],y4);
}
Zmierzona wydajność tego jądra to około 5,6 operacji FP na cykl, chociaż spodziewałbym się, że będzie to dokładnie 4x wydajność wersji skalarnej, tj. 4,1,6 = 6,4 FP operacji na cykl.
Biorąc pod uwagę zmianę wagi (dzięki za zwrócenie uwagi), harmonogram wygląda następująco:
Wygląda na to, że harmonogram się nie zmienia, chociaż po movss
operacji jest dodatkowa instrukcja, która przenosi wartość wagi skalarnej do rejestru XMM, a następnie używa shufps
do skopiowania tej wartości skalarnej w całym wektorze. Wygląda na to, że wektor wagi jest gotowy do użycia mulps
w czasie, biorąc pod uwagę opóźnienie przełączania z obciążenia do domeny zmiennoprzecinkowej, więc nie powinno to powodować żadnych dodatkowych opóźnień.
movaps
(Wyrównane, pakowane ruch), addps
i mulps
instrukcje, które są używane w tym kernelu (sprawdzony z kodem montażowej) mają taką samą przepustowość jak i opóźnienie ich skalarnych wersji, więc nie powinny ponosić żadnych dodatkowych opóźnień albo.
Czy ktoś ma pomysł, na co wydaje się ten dodatkowy cykl na 8 cykli, zakładając, że maksymalna wydajność tego jądra to 6,4 PR na cykl i działa z szybkością 5,6 PR na cykl?
Przy okazji, oto jak wygląda rzeczywisty montaż:
…
Block x:
movapsx (%rax,%rcx,4), %xmm0
movapsx 0x10(%rax,%rcx,4), %xmm1
movapsx 0x20(%rax,%rcx,4), %xmm2
movapsx 0x30(%rax,%rcx,4), %xmm3
movssl (%rdx,%rcx,4), %xmm4
inc %rcx
shufps $0x0, %xmm4, %xmm4 {fill weight vector}
cmp $0x32, %rcx
mulps %xmm4, %xmm0
mulps %xmm4, %xmm1
mulps %xmm4, %xmm2
mulps %xmm3, %xmm4
addps %xmm0, %xmm5
addps %xmm1, %xmm6
addps %xmm2, %xmm7
addps %xmm4, %xmm8
jl 0x401ad6 <Block x>
…
źródło
shufps
instrukcja dodaje 1 cykl na 1,6 iteracji?" To trudne ...shufps
powinny być bezpośrednio dostępne dlamultps
operatora, ponieważ są to obie domeny FPOdpowiedzi:
Spróbuj użyć profilowania EMON w Vtune lub innego równoważnego narzędzia, takiego jak oprof
Profilowanie EMON (monitorowanie zdarzeń) => jak narzędzie oparte na czasie, ale może powiedzieć, jakie zdarzenie wydajnościowe powoduje problem. Chociaż powinieneś najpierw zacząć od profilu opartego na czasie, aby sprawdzić, czy jest jakaś konkretna instrukcja, która wyskakuje. (I być może powiązane wydarzenia, które mówią ci, jak często w tym adresie IP występował stragan emerytalny).
Aby skorzystać z profilowania EMON, musisz przejrzeć listę zdarzeń, od „zwykłych podejrzanych” do ...
Tutaj zacząłbym od błędów w pamięci podręcznej, wyrównania. Nie wiem, czy procesor, którego używasz, ma licznik ograniczeń portu RF - powinien - ale profilowanie EMON dodałem dawno temu i nie wiem, jak dobrze nadążają, dodając zdarzenia odpowiednie dla mikroarchitektury.
Możliwe jest również, że jest to interfejs użytkownika, pobieranie instrukcji, przeciągnięcie. Ile bajtów jest w tych instrukcjach? Są też wydarzenia związane z EMON.
Odpowiadając na komentarz, że Nehalem VTune nie widzi zdarzeń L3: nieprawda. Oto rzeczy, które dodałem do komentarza, ale nie pasowały:
W rzeczywistości istnieją liczniki wydajności dla LL3 / L3 $ / tak zwanego Uncore. Byłbym niezmiernie zaskoczony, gdyby VTune ich nie obsługiwał. Zobacz http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdfwskazuje na VTune i inne narzędzia, takie jak PTU. W rzeczywistości nawet bez zdarzeń LL3, jak mówi David Levinthal: „Procesor Intel® Core ™ i7 ma„ zdarzenie opóźnienia ”, które jest bardzo podobne do zdarzenia EAR z danymi rodziny procesorów Itanium®. To zdarzenie jest ładowane, rejestrując liczbę cykli pomiędzy wykonaniem rozkazu a faktycznym dostarczeniem danych. Jeśli zmierzone opóźnienie jest większe niż minimalne opóźnienie zaprogramowane w MSR 0x3f6, bity 15: 0, to licznik jest zwiększany. Przepełnienie licznika uzbraja mechanizm PEBS i przy następnym zdarzenie spełniające próg opóźnienia, zmierzone opóźnienie, adres wirtualny lub liniowy oraz źródło danych są kopiowane do 3 dodatkowych rejestrów w buforze PEBS. Ponieważ adres wirtualny jest przechwytywany w znanej lokalizacji, sterownik próbkujący mógłby również wykonać translację wirtualną na fizyczną i przechwycić adres fizyczny. Fizyczny adres identyfikuje lokalizację domową NUMA i zasadniczo umożliwia analizę szczegółów zajętości pamięci podręcznej. ”Wskazuje również, na stronie 35, na zdarzenia VTune, takie jak L3 CACHE_HIT_UNCORE_HIT i L3 CACHE_MISS_REMOTE_DRAM. Czasami trzeba sprawdzić numeryczne kody i zaprogramuj je w interfejsie niższego poziomu VTune, ale myślę, że w tym przypadku jest to widoczne w ładnym interfejsie użytkownika.
OK, w http://software.intel.com/en-us/forums/showthread.php?t=77700&o=d&s=lr programista VTune w Rosji (chyba) „wyjaśnia”, że nie można samplować na Uncore wydarzenia.
Myli się - możesz na przykład włączyć tylko jeden procesor i próbkować w sensowny sposób. Uważam również, że istnieje możliwość zaznaczenia brakujących danych L3, gdy powracają do procesora. W rzeczywistości L3 wie, do którego procesora zwraca dane, więc na pewno możesz próbkować. Możesz nie wiedzieć, który hiperwątek, ale ponownie możesz wyłączyć, przejść do trybu pojedynczego wątku.
Ale wygląda na to, że co jest dość powszechne, musiałbyś pracować WOKÓŁ VTune, a nie z nim, aby to zrobić.
Najpierw wypróbuj profilowanie opóźnienia. To jest całkowicie wewnątrz procesora i ludzie z VTune raczej nie zepsuli go zbytnio.
I powtarzam, prawdopodobieństwo jest takie, że problem tkwi w rdzeniu, a nie w poziomie L3. Więc VTune powinien być w stanie sobie z tym poradzić.
Wypróbuj „Cycle Accounting” według Levinthal.
źródło
off-core
części rdzenia, więc nie ma dostępnych liczników zdarzeń wydajności dla tej części. Dlatego trudno jest oszacować błędy pamięci podręcznej itp.