Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.08.20;
Скачать: CL | DM;

Вниз

Измерение интервалов, меньших 1 mS.   Найти похожие ветки 

 
JohnKorsh ©   (2006-07-04 11:08) [0]

Извините, но вопрос несколько длинноват.
Для работы с короткими интервалами времени (< 1 mS) пытаюсь использовать команду RDTSС. (Она возвращает в регистрах EDX:EAX число тактов с момента включения процессора.)
Пытаюсь “откалибровать” программу-измеритель - по таймеру Delphi: cчитываю RDTSС_1, запускаю таймер на 100 ms, по окончании считываю RDTSС_2. Разница значений (RDTSC_2 - RDTSC_1) “плавает” не на тысячи, что объяснимо, а на десятки миллионов. Не поможет ли кто понять почему такой разброс?

Вот  функция, использованная для чтения числа тактов с момента включения процессора:

 function TForm1.RDTSC: comp;

//*************************************************
 const
  D32 = $66;
 var
   TimeStamp                           : record
 case byte of
   1: (Whole:  comp);
   2: (Lo, Hi: LongInt);
 end;

//--------------------------------------------------------------------------

 begin
  asm
   db $0F; db $31;                     // BASM не поддерживает команду RDTSC
{$ifdef Cpu386}
   mov    [TimeStamp.Lo],eax           // младшее двойное слово
   mov    [TimeStamp.Hi],edx           // старшее двойное слово
{$else}
   db D32
   mov    word ptr TimeStamp.Lo,AX     // mov    [TimeStamp.Lo],eax    - младшее двойное слово.
   db D32
   mov    word ptr TimeStamp.Hi,DX     // mov    [TimeStamp.Hi],edx    - старшее двойное слово.
{$endif}
   end;
   Result := TimeStamp.Whole;
 end;

С таймером работаю обычным образом, функцию RDTSC вызываю сразу после Timer1.Enabled := True и первой строкой события Tick таймера.


 
Jeer ©   (2006-07-04 11:14) [1]

Потому, что ОС класса windows не являются ОС реального времени.
В разумных пределах их возможно адаптировать под конкретные задачи, точнее программы адаптировать под конкрентные задачи с учетов особенностей работы в мультизадачной среде.


 
Rial ©   (2006-07-04 11:31) [2]

Дело в том, что обычный таймер (как я понял, именно он используется),
способем обрабатывать "тики" с минимальной частотой в 55 милисекунд.
Поэтому у Вас тикает он не каждый 100, а каждые 110, и , иногда, 55 милисекунд.
Выход - использование мультимедийного таймера.
TimeSetEvent из модуля MMSystem посоветую.


 
Desdechado ©   (2006-07-04 11:41) [3]

> Пытаюсь “откалибровать” программу-измеритель - по таймеру Delphi
Это как измерять диаметр сверла линейкой с метровой шкалой.
Лучшее, что мне удавалось получить простым таймером, это что-то около 12 мс, а обычно около 40 мс. А все потому, что Jeer ©   (04.07.06 11:14) [1]
Т.е. программы могут замирать или замедляться по мановению ОС и нельзя ее заставить выполнять что-то в реальном времени (хоть и есть такой приоритет, но он может поставить раком всю ОС) в ущерб другим процессам, в число которых и сама ОС входит.


 
второе явление Чапаева народу   (2006-07-04 11:43) [4]


> Дело в том, что обычный таймер (как я понял, именно он используется),
> способем обрабатывать "тики" с минимальной частотой в 55
> милисекунд.

В системах линейки NT это регулируется. ХР, к примеру, "тикает" каждые 15 мс. А вообще я бы timeSetEvent() использовал. Даёт миллисекундные интервалы даже в девяностопятке...


 
Jeer ©   (2006-07-04 12:27) [5]

Да не так уж все и плохо:))

Не говоря уже об RDTSC, с помощью того же GetTickCount можно убедиться, что системный таймер (обертка TTimer) тикает довольно точно даже без поднятия приоритетов.

Надо только помнить о многозадачности и недопускать наличия сервисов и программ, отнимающих значительную часть процессорного времени.

Поскольку slice на платформах NT лежит в районе 10-20 ms (NT, w2k,XP, server, station), то "тиканье" с временными интервалами 100 ms и более наверняка приведет к спорадическом отклонениям от заданного интервала.
"Тиканье" с интервалом меньше slice - невозможно. (при исп. TTimer)
Опять же "тиканье" производится с шагом в slice, т.е. при slice=10 ms интервал составит T = 10*N, где N - целое число >=1

Пример:

TTimer.interval = 100 ms
Число тиков 1000
Среднее значение 100.1 ms
Макс. = 101 ms
Мин. = 100 ms

TTimer.interval = 10 ms
Число тиков 1000
Среднее значение 10.02 ms
Макс. = 10.09 ms
Мин. = 10.0 ms

Если же в момент выполнения такой программы запустить, дефрагментацию, смотреть фильм и искать наибольшее простое число, то результат будет несравненно хуже.


 
Rial ©   (2006-07-04 15:51) [6]


> Jeer ©   (04.07.06 12:27) [5]


Попробуй вывести на экран каждый интервал между тиками этого таймера.
Ты очень сильно удивишься, увидев, что некоторые интервалы были
по 55 секунд.


 
Jeer ©   (2006-07-04 16:14) [7]

Rial ©   (04.07.06 15:51) [6]

Не удивлюсь, т.к. их там нет.
См.
Макс. = 10.09 ms
Мин. = 10.0 ms


 
Cash ©   (2006-07-04 17:02) [8]

JohnKorsh ©:
А чего там калибровать???
Там надо считать такты (RDTSC), а еще надо считать среднюю тактовую
частоту. Такты делим на такты в секунду, получаем тот промежуток
времени, которым мы проработали. Все просто!


const
  DelayTime = 500;

Function GetCPUSpeed: DWord;
var
  TimerHi, TimerLo: DWORD;
begin
  asm
    dw  310Fh
    mov TimerLo, eax
    mov TimerHi, edx
  end;
  Sleep(DelayTime);
  asm
    dw  310Fh
    sub eax, TimerLo
    sbb edx, TimerHi
    mov TimerLo, eax
    mov TimerHi, edx
  end;
  Result := Trunc(TimerLo / (1000.0 * DelayTime)); // MHz
end;


 
Jeer ©   (2006-07-04 17:45) [9]

Cash ©   (04.07.06 17:02) [8]

Несколько не точный метод.
Завышает истинную частоту в зависимости от общей загрузки проца.
Необходимо поиграть приоритетами.



Страницы: 1 вся ветка

Текущий архив: 2006.08.20;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.053 c
3-1150353422
s_t_d
2006-06-15 10:37
2006.08.20
Отображение длинных текстов в DBGrid


2-1154290722
<X>
2006-07-31 00:18
2006.08.20
Цвет текста


2-1153952634
vain
2006-07-27 02:23
2006.08.20
Проект привык к dll


15-1153770062
ronyn
2006-07-24 23:41
2006.08.20
Как установить компонент без файла пакета?


2-1154522690
AlexanderMS
2006-08-02 16:44
2006.08.20
Ассоциация программы с файлами.