Wydajność pętli kodu C [ciąg dalszy]

83

To pytanie jest kontynuacją mojego pytania tutaj (za radą Mistycznego):

Wydajność pętli kodu C.


Kontynuując moje pytanie, kiedy używam instrukcji spakowanych zamiast instrukcji skalarnych, kod używający funkcji wewnętrznych wyglądałby bardzo podobnie:

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:

harmonogram

Wygląda na to, że harmonogram się nie zmienia, chociaż po movssoperacji jest dodatkowa instrukcja, która przenosi wartość wagi skalarnej do rejestru XMM, a następnie używa shufpsdo skopiowania tej wartości skalarnej w całym wektorze. Wygląda na to, że wektor wagi jest gotowy do użycia mulpsw 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), addpsi mulpsinstrukcje, 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ż:

Ricky
źródło
Więc wydaje mi się, że teraz pytanie brzmi: "Dlaczego shufpsinstrukcja dodaje 1 cykl na 1,6 iteracji?" To trudne ...
Mysticial
spodziewałbym się, że nie będzie to miało narzutów, ponieważ dane wyjściowe shufpspowinny być bezpośrednio dostępne dla multpsoperatora, ponieważ są to obie domeny FP
Ricky
Łatwo się dowiedzieć. Upewnij się, że wektor wagi nie zawiera żadnych zdenormalizowanych wartości wartości. Wypróbuj pętlę bez instrukcji odtwarzania losowego. Nie przyniesie to żadnych użytecznych wyników, ale może dowiesz się, która instrukcja kosztuje dodatkowe cykle (podejrzewam oczywiście, że tasowanie).
Gunther Piez
@Mystical: widzę 0,75 cykli na iterację pętli. (Czy to nie mój komentarz o używaniu 5 cykli zamiast 4, który doprowadził cię do odpowiedzi tam ... :-))
Gunther Piez
3
Po pierwsze, teraz potrzebujesz 4x przepustowości pamięci podręcznej. Jak duże są rozmiary danych? Czy mieszczą się w pamięci podręcznej L1?
Mysticial

Odpowiedzi:

3

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.

Krazy Glew
źródło
Dziękuję za twoją reakcję. Używam VTune do analizy mojej aplikacji, ale problem z architekturą nehalem polega na tym, że pamięć podręczna L3 należy do off-coreczęś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.
Ricky,
W rzeczywistości istnieją liczniki wydajności dla LL3 / L3 $ / tak zwanego Uncore. Byłbym niezmiernie zaskoczony, gdyby VTune ich nie obsługiwał. Zobacz software.intel.com/sites/products/collateral/hpc/vtune/…
Krazy Glew
Napisałem więcej niż zmieściłoby się w komentarzu, próbowałem przenieść go do odpowiedzi i uporządkować oryginalny komentarz, ale komentarze można edytować tylko przez 5 minut. Krótka wersja: VTune pozwala zobaczyć chybienia pamięci podręcznej L3. Nawet bez obsługi Uncore, używając profilowania opóźnień - i ma obsługę Uncore.
Krazy Glew
I ogólnie podejrzewam, że twoim problemem nie są chybienia w pamięci podręcznej L3. Bardziej prawdopodobne jest zdarzenie frontendowe.
Krazy Glew
@KrazyGlew: Zgadujesz, że jest Rosjaninem z Federacji Rosyjskiej. Oto jego profil na LinkedIn - linkedin.com/in/vtsymbal