🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.asm
6 messages
6 total messages Started by Ryouk Sun, 23 Sep 2007 10:13
Pomiar cykli procesora
#1498
Author: Ryouk
Date: Sun, 23 Sep 2007 10:13
39 lines
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
#1499
Author: Wojciech Muła
Date: Sun, 23 Sep 2007 11:26
13 lines
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
#1500
Author: Bernard
Date: Sun, 23 Sep 2007 15:03
21 lines
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
#1502
Author: Bogdan (bogdro)
Date: Sun, 23 Sep 2007 15:42
74 lines
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
#1503
Author: Ryouk
Date: Sun, 23 Sep 2007 16:37
20 lines
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
#1501
Author: Wojciech Muła
Date: Thu, 27 Sep 2007 12:08
35 lines
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