Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];

Вниз

Измерение интервалов, меньших 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.044 c
1-1152090839
jiny
2006-07-05 13:13
2006.08.20
Криптование и архивация потока TMemoryStream


4-1145334498
Elen
2006-04-18 08:28
2006.08.20
OPC Server


15-1153658347
ronyn
2006-07-23 16:39
2006.08.20
сообщения принтера


1-1152169596
RDS
2006-07-06 11:06
2006.08.20
Кнопка приложения на панели задач


3-1150218131
starling13
2006-06-13 21:02
2006.08.20
TIBTransaction.Rollback





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский