Thread View: pl.comp.lang.asm
6 messages
6 total messages
Started by Ryouk
Sun, 23 Sep 2007 10:13
Pomiar cykli procesora
Author: Ryouk
Date: Sun, 23 Sep 2007 10:13
Date: Sun, 23 Sep 2007 10:13
39 lines
1877 bytes
1877 bytes
Cześć, mam pytanie, które wynikło z programu w C++, ale dotyczy raczej
assemblera. Napisałem sobie taką wstawkę do liczenia taktów procesora od
ostatniego resetu.
#v+
inline uint64_t rdtsc() {
uint32_t lo, hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (static_cast<uint64_t>(hi) << 32 | lo);
}
#v-
Dla niezorientowanych - przy użyciu RDTSC pobiera 64 bitową liczbę
określającą ilość cykli procesora od ostatniego resetu. A że rejestry są
32 bitowe, to muszę to odpowiednio przesunąć i zamienić w 64 bity.
Dalej dwa razy pod rząd wywołuję tę funkcję, a wyniki odejmuję.
G++ generuje taką wstawkę:
#v+
#APP
rdtsc
#NO_APP
movl %edx, -24(%ebp)
movl %eax, -20(%ebp)
#APP
rdtsc
#NO_APP
#v-
Wg manuala i opinii jednego asemblerowca te movy to jakieś 2 cykle, a mój
program daje wynik około 44 cykli. Na komputerze znajomego wynik to 35.
Rozumiem, że w systemie siedzi sobie planista i rozdziela czas procesora,
ale wydaje mi się, że daje tego czasu więcej niż 2 cykle :)
No więc z czego to wynika?
Re: Pomiar cykli procesora
Author: Wojciech Muła
Date: Sun, 23 Sep 2007 11:26
Date: Sun, 23 Sep 2007 11:26
13 lines
1247 bytes
1247 bytes
Ryouk wrote: > Wg manuala i opinii jednego asemblerowca te movy to jakieś 2 cykle, 2 cykle **maszynowe**. > a mój program daje wynik około 44 cykli. Na komputerze znajomego > wynik to 35. RDTSC czyta licznik cykli **zegarowych** -- na cykl maszynowy przypada kilka-kilkanaście cykli zegarowych. Żeby zmierzyć liczbę cykli maszynowych musiałbyś czytać inne MSR-y. w.
Re: Pomiar cykli procesora
Author: Bernard
Date: Sun, 23 Sep 2007 15:03
Date: Sun, 23 Sep 2007 15:03
21 lines
1677 bytes
1677 bytes
Wojciech Muła wrote: > Ryouk wrote: >> Wg manuala i opinii jednego asemblerowca te movy to jakieś 2 cykle, > > 2 cykle **maszynowe**. > >> a mój program daje wynik około 44 cykli. Na komputerze znajomego >> wynik to 35. > > RDTSC czyta licznik cykli **zegarowych** -- na cykl maszynowy > przypada kilka-kilkanaście cykli zegarowych. Żeby zmierzyć > liczbę cykli maszynowych musiałbyś czytać inne MSR-y. Nic podobnego. We współczesnych procesorach x86 nie ma czegoś takiego, jak "cykl maszynowy", w jednym cyklu zegara kończy się wykonanie kilku instrukcji. Zaobserwowany efekt można wytłumaczyć na 100 sposobów - umiejscowienie danych w hierarchii pamięci, serializacja wynikająca z użycia instrukcji rdtsc i parę innych zjawisk. Nie zdziwiłby mnie żaden wynik z przedziału od 5 do 400 cykli.
Re: Pomiar cykli procesora
Author: Bogdan (bogdro)
Date: Sun, 23 Sep 2007 15:42
Date: Sun, 23 Sep 2007 15:42
74 lines
3306 bytes
3306 bytes
Ryouk pisze:
> Cześć, mam pytanie, które wynikło z programu w C++, ale dotyczy raczej
> assemblera. Napisałem sobie taką wstawkę do liczenia taktów procesora od
> ostatniego resetu.
>
> #v+
> inline uint64_t rdtsc() {
> uint32_t lo, hi;
>
> __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
>
> return (static_cast<uint64_t>(hi) << 32 | lo);
> }
> #v-
>
> Dla niezorientowanych - przy użyciu RDTSC pobiera 64 bitową liczbę
> określającą ilość cykli procesora od ostatniego resetu. A że rejestry są
> 32 bitowe, to muszę to odpowiednio przesunąć i zamienić w 64 bity.
>
> Dalej dwa razy pod rząd wywołuję tę funkcję, a wyniki odejmuję.
> G++ generuje taką wstawkę:
>
> #v+
> #APP
> rdtsc
> #NO_APP
> movl %edx, -24(%ebp)
> movl %eax, -20(%ebp)
> #APP
> rdtsc
> #NO_APP
> #v-
>
> Wg manuala i opinii jednego asemblerowca te movy to jakieś 2 cykle, a mój
> program daje wynik około 44 cykli. Na komputerze znajomego wynik to 35.
>
> Rozumiem, że w systemie siedzi sobie planista i rozdziela czas procesora,
> ale wydaje mi się, że daje tego czasu więcej niż 2 cykle :)
>
> No więc z czego to wynika?
Poza podaną już odpowiedzią, że RDTSC może potrwać, może to być też
np. przekroczenie granicy linii pamięci podręcznej (cache line), a
więc czytanie z dalszych pamięci, co kosztuje. RDTSC nie serializuje
instrukcji, co znaczy, że poprzednie instrukcje mogły się jeszcze nie
zakończyć.
W każdym razie testuj czas wykonania następującym kodem:
xor eax, eax ; tak, musi być EAX
cpuid
rdtsc
; tu zachowaj EAX i EDX
; tu blok mierzonych instrukcji
xor eax, eax
cpuid
rdtsc
; tu wylicz wynik
CPUID gwarantuje, że wszystkie instrukcje przed RDTSC się zakończą i
mierzymy tyko to, co trzeba. Zacznij od pustego bloku do mierzenia,
aby sprawdzić, ile czasu zajmuje "obsługa", czyli XOR, CPUID i RDTSC.
Zerowanie EAX przed CPUID gwarantuje, że czas wykonania tej
instrukcji będzie stały.
P.S. Piszesz w UTF, a Twój program do news wysyła, że piszesz w ISO,
więc u niektórych pojawią się krzaczki.
--
Pozdrawiam/Regards - Bogdan (Linux & FreeDOS)
Kurs asemblera x86 (DOS & Linux): http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
Rozmawiaj bezpiecznie: www.JabberPL.org Surfuj anonimowo: tor.eff.org
Re: Pomiar cykli procesora
Author: Ryouk
Date: Sun, 23 Sep 2007 16:37
Date: Sun, 23 Sep 2007 16:37
20 lines
1715 bytes
1715 bytes
On 2007-09-23, Bogdan (bogdro) <bogdan@poczta.gazeta.pl> wrote: > Poza podaną już odpowiedzią, że RDTSC może potrwać, może to być też > np. przekroczenie granicy linii pamięci podręcznej (cache line), a > więc czytanie z dalszych pamięci, co kosztuje. RDTSC nie serializuje > instrukcji, co znaczy, że poprzednie instrukcje mogły się jeszcze nie > zakończyć. > W każdym razie testuj czas wykonania następującym kodem: Dzięki, zaraz potestuję. > CPUID gwarantuje, że wszystkie instrukcje przed RDTSC się zakończą i > mierzymy tyko to, co trzeba. Hm, do tej pory zakładałem, że tak było. Dobrze wiedzieć, że nie. > P.S. Piszesz w UTF, a Twój program do news wysyła, że piszesz w ISO, > więc u niektórych pojawią się krzaczki. Bo na ogół piszę w ISO-8859-2, nie mam zielonego pojęcia dlaczego nagle wyleciał mi UTF. Mam nadzieję, że tym razem będzie dobrze.
Re: Pomiar cykli procesora
Author: Wojciech Muła
Date: Thu, 27 Sep 2007 12:08
Date: Thu, 27 Sep 2007 12:08
35 lines
2373 bytes
2373 bytes
Bernard wrote: > Nic podobnego. We współczesnych procesorach x86 nie ma czegoś takiego, > jak "cykl maszynowy", w jednym cyklu zegara kończy się wykonanie kilku > instrukcji. Faktycznie, może cykl maszynowy to złe nazwa. Cykl potoku -- to jest dobre określenie. I nigdzie nie mogę znaleźć potwierdzenia, że jeden cykl zegara = jeden cykl potoku, najpewniej źle szukam. Zrobiłem taki prosty test: zmierzyłem na moim P2 za pomocą PMC (performance monitors counters) w ilu cyklach wykonano co najmniej jeden mikrorozkaz i ile w sumie wykonano mikrorozkazów: uops_retired = 61055189 (cykle) uops_total = 139870771 (liczba - ok. 2,3 mikrops/cykl) Odczytałem też przed i po pomiarze wartości z RDTSC: rdtsc1 = 2962091758409 rdtsc2 = 2963298554276 (rdtsc2 - rdtsc1)/uops_retired wynosi ok. 20, czyli średnio co 9 cykli procesor wykonuje jeden mikrorozkaz. Byłoby aż tak tragicznie? Może rzeczywiście średnie opóźnienie, np. spowodowane przez nietrafienia w cache, wyjdą po 8-9 cykli na mikrorozkaz. Ale jeśli nie, to pytanie brzmi: co tak naprawdę mierzą PMC i RDTSC, czy liczą te same "cykle"? > Zaobserwowany efekt można wytłumaczyć na 100 sposobów - umiejscowienie > danych w hierarchii pamięci, serializacja wynikająca z użycia instrukcji > rdtsc i parę innych zjawisk. Nie zdziwiłby mnie żaden wynik z przedziału > od 5 do 400 cykli. RDTSC nie serialzuje. w.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads