Pomiar czasu wykonania programu

0

Chciałbym zrobić coś takiego:
-z debugera zrobić zrzut do pliku textowego wykonanych instrukcji(w asm oczywiście)
-napisać prog/skrypt który rozpoznałby te instrukcje i z tabeli dokumentacji Intela obliczył liczbe taktów odpowiadającą całemu progsowi

Teraz mam obawy czy to będzie wiarygodne - opóźnienia pamięci itd
Czy jest debuger który coś takiego oferuje (zrzut "przemielonych" instrukcji) albo czy nawet sam by to obliczył - ewentualnie inny program (zamierzam jeszcze pobawić programem intela Vtune - jak ktoś ma doświadczenia z tym profilerem to mógłby opisać jak się nim robi pomiar wydajności itd)

0
Fallen napisał(a)

Chciałbym zrobić coś takiego:
-z debugera zrobić zrzut do pliku textowego wykonanych instrukcji(w asm oczywiście)
-napisać prog/skrypt który rozpoznałby te instrukcje i z tabeli dokumentacji Intela obliczył liczbe taktów odpowiadającą całemu progsowi

Bezwartościowe i niewykonalne.

0

Jeżeli to ma działać na i386 pod systemem operacyjnym, to pomiar czasu wykonania dużo ci nie da, bo nigdy nie wiesz, czy i kiedy system nie wydziedziczy ci zadania na jakiś czas.
Jeżeli to jest na jakiejś innej platformie (wbudowanej) to taki pomiar wtedy ma sens.

0

Zrzut instrukcji asmowych możesz wykonać chociażby w gdb przez wydanie mu komendy
disassemble nazwa_funkcji

Możliwe, że jest też jakiś sposób na "automagiczne" wylistowanie wszystkich, niestety do tego jeszcze nie doszedłem.

Co do pomiaru czasu, to w C masz funkcję clock(), w Linuksach jest też komenda time. Jeśli chcesz zejść jeszcze niżej to w procesorach x86 od czasów Pentium jest instrukcja rdtsc, która zwraca ilość cykli procesora od czasu jego uruchomienia jako nieznakowaną 64-bitową wartość całkowitoliczbową. Przykładowy kod wykorzystujący tą instrukcję mógłby wyglądać tak (assembler wg. GAS, czyli składnia AT&T) :

.global rdtsc
.type rdtsc,@function
rdtsc:
	xorl %eax,%eax
	cpuid
	rdtsc
	ret

cpuid występuje tutaj jako instrukcja serializująca, powodująca zakończenie wszystkich potoków przetwarzania procesora, jako że mogłyby one wpłynąć na dokładność wartości zwracanej przez rdtsc. Zerowanie %eax wykonywane jest w celu poprawnego wykonania cpuid (która ma ustalone działanie tylko gdy w tym rejestrze jest 0, 1, 2 lub 3).

Do tego wywołujący powyższą funkcję kod w C :

unsigned long long rdtsc(void);

#include <stdio.h>

int main(void)
{
	unsigned long long bla = rdtsc();
	printf("%llu",bla);

	return 0;
}

Mam nadzieję że troszkę chociaż pomogłem.

0

Z czego rdtsc jest bezużyteczne bo dla każdego rdzenia/procesora masz oddzielny licznik...

0

Jak już to dla każdego procesora, co w sumie rozumie się samo przez siebie - ten licznik jest wbudowany fizycznie w procesor, więc wydaje się oczywiste że jego odczyt z każdego procesora będzie inny. Z drugiej strony, jeśli założymy, że obydwa procesory zostały włączone w tym samym momencie (co jest dość rozsądnym, moim zdaniem, założeniem) to odczyty z nich powinny być co najmniej podobne.

Co do rdzeni - możesz podesłać jakieś źródło? Ani Instruction Set Reference, ani System Programming Guide nie mówią nic o kwestii tego licznika na procesorach wielordzeniowych, wspominają tylko o tym, że nie jest to funkcja serializująca - stąd w moim kodzie cpuid, który taką funkcją jest i IMHO powinien poczekać na zakończenie operacji na wszystkich rdzeniach. No ale oczywiście mogę się mylić.

0
GlupiTuman napisał(a)

Z drugiej strony, jeśli założymy, że obydwa procesory zostały włączone w tym samym momencie (co jest dość rozsądnym, moim zdaniem, założeniem) to odczyty z nich powinny być co najmniej podobne.

Przy dzisiejszych technikach chwilowego odciążania procesorów itp. nie liczyłbym na podobne wyniki.

stąd w moim kodzie cpuid, który taką funkcją jest i IMHO powinien poczekać na zakończenie operacji na wszystkich rdzeniach. No ale oczywiście mogę się mylić.

CPUID używany jest praktycznie we wszystkich przykładach użycia więc to chyba dobre podejście :)

Natomiast z samym RDTSC wiąże się śmieszny bug w jednym starym programie... Nie pamiętam do czego była używana ta instrukcja, ale odczytywane było tylko 32b wartości, co powodowało, że licznik dosyć szybko ulegał przekręceniu i wychodziły kosmiczne rezultaty :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1