Delphi i problem z niedokładnym timerem

0

Witam! Pracuję obecnie w Code Gear 2007 i mam następujący problem. Zauważyłem, że komponent Timer zachowuje się w bardzo dziwny sposów. Jeżeli ustawi się Interval na 1000 - czyli 1 sekundę to czas jest liczony PRAWDOPODOBNIE DOBRZE - nie mam możliwości sprawdzić tego czy ta jedna sekunda jest faktycznie DOKŁADNIE jedną sekundą. Problem polega jednak na tym, że zmniejszenia Intervala do 100 powoduje już duży błąd - operacje nie są wykonywane co 1/10 sekundy tylko z większym odstępem czasu. Kolejne zmniejszanie np. na 10 powoduje kolejny jeszcze większy a właściwie POTĘŻNY błąd. Prawdopodobnie Interval 1 w ogóle nie działa - tzn działa tak samo jak 10. Sprawdzałem to wstawiając na formę 3 timery - 1 z Intervalem na 1000 drugi na 100 a trzeci na 10 - pierwszy zwiększał jedną zmiennną o 1000 drugi inną o 100 a trzeci jeszcze inną o 10 - później wszystkie zmienne wypisywało do osobnych editów. Wyniki tego programu umieszczam poniżej - teoretycznie wszystkie liczby POWINNY BYĆ równe:

PO 60 SEKUNDACH

Timer z intervalem 1000 = 60000
Timer z intervalem 100 = 55000
Timer z intervalem 10 = 38550

Widać, że szczególnie przy ostatnim błąd jest po prostu OLBRZYMI!
Moje pytanie - bo w sumie nigdy nie zwracałem na to uwagi - czy Delphi zawsze miał takiego NIEDOKŁADNEGO timera - bo pracowałem we wcześniejszych wersjach ale jakoś tego nie zauważałem - czy wina może być np. po stronie 2 rdzeniowego procesora Core2Duo na którym pracuję? Wiem że np. niektóre starsze gry mają właśnie problem z dziwnym spowalnianiem na 2 rdzeniowych prockach - a zakładam, że Borland nigdy nie modyfikował samego komponentu Timer. Jeśli ktoś ma jakieś pomysły to proszę o informacje!</image>

0

To nie "wina" Delphi, ani Borland'a, tylko tego, że Winapi obsługuje (przez SetTimer) timer jako low resolution timer (zegar niskiej rozdzielczości). To w pełni normalne i nie należy tego używać do odliczania czasu, tylko do wykonywania zadań asynchronicznych (!) periodycznie.

Istnieją inne konstrukcje i algorytmy oferujące podwyższanie rozdzielczości, na przykład odliczanie ze zbieżnością: jeśli możesz zagwarantować dokładność w zakresie do 100ms, to - jeśli zdarzenie ma wystąpić powyżej 200ms - czekasz timerem niskiej rozdzielczości, a w przeciwnym razie zatrzymujesz timer i albo korzystasz z timera wysokiej rozdzielczości, albo wprost z zegara, w pętli sprawdzając jego wartości. Oczywiście algorytmy te obciążają system, ale dają większą dokładność.

Swoją drogą błąd jaki otrzymałeś wcale nie jest taki duży, przy zegarze niskiej rozdzielczości, jak Ci się zdaje.

0

aha to dziękuję za informacje!

0

Napisz wlasny timer korzystajacy z "zegara wysokiej rozdzielczosci":
tworzysz watek (najlepiej z podwyzszonym priorytetem)
i w petli sprawdzasz ile czasu minelo. WinAPI ma (chyba) dwie funkcje do tego QueryPerformance*.

ps. o ile dobrze pamietam to komponenty DirectX maja tez swoj - podobno dokladniejszy od zwyklego TTimer) timer.

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