Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Сокровищница
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  02:24[Войти] | [Зарегистрироваться]

Обсуждение материала
Использование команды RDTSC процессора Pentium для работы с малыми временными интервалам
Полный текст материала


Цитата или краткий комментарий:

«... В одной толстой книге нашел интересное использование команды RDTSC процессора Pentium для работы с малыми временными интервалами. Я думаю, что эта функция может найти широкое применение (в таймерах, управлении внешними устройствами, научных исследованиях). ...»


Важно:
  • Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
  • Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
  • При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.



Добавить свое мнение.

Результаты голосования
Оценка содержания

  Содержит полезные и(или) интересные сведения
[1]758.3%
 
  Ничего особенно нового и интересного
[2]433.3%
 
  Написано неверно (обязательно укажите почему)
[3]18.3%
 
Всего проголосовали: 12

Оценка стиля изложения

  Все понятно, материал читается легко
[1]7100%
 
  Есть неясности в изложении
[2]00%
 
  Непонятно написано, трудно читается
[3]00%
 
Всего проголосовали: 7




Смотрите также материалы по темам:
[Таймеры]

Комментарии жителей
Отслеживать это обсуждение

Всего сообщений: 16

03-04-2009 09:27
Вот назрел небольшой вопрос. При использовании функции QueryPerformanceCounter в тестовом приложении столкнулся с ситуацией, когда при последовательном вызове этой функции следующее возвращаемое значение тактов было ниже, чем предыдущее. Интересно, с чем это связано. Возможно, проблема в том, что мой процессор двухъядерный, но тогда выходит, что этой функции присущи те же проблемы на многопроцессорных системах, что и в случае RDTSC. Или все таки я что-то упустил?


26-10-2007 08:32
Использование RDTSC таймера на многопроцессорной системе
Я использовал RDTSC таймер для мониторинга выполнения считывания данных с порта платы ввода/вывода на двухядерном процессоре. Так как RDTSC значение счетчика на разных ядрах может отличаться, то следует отслеживать с какого процессора считывается счетчик. Или как минимум использовать SetThreadAffinityMask

Антон Григорьев
использование QueryPerformanceCounter вносило неоправданные и непредсказуемые задержки до 10мкс. Так что у меня есть вопросы к использованию данного таймера.
Покрайней мере использование QueryPerformanceCounter в коротком цикле, по крайней мере, не рационально

Подробнее на
Реализация эффективного многопоточного приложения в WinAPI
http://forum.ixbt.com/topic.cgi?id=26:37039

Используемые функции
//Для точного определения времени
function GetCPUCounter: Int64; register;
asm
  rdtsc
end;

// Получение индекса ядра
function GetCPUIndex : Longword; register;
  asm  //EAX, EDX, ECX - Универсальные регистры можно смело их использовать
   push ebx  // а вот EBX надо бы сохранить
   mov eax,1 // режим работы cpuid
   cpuid
   shr ebx, 24 // сдвигаем впрво 24
   and ebx,$f // маскируем
   mov eax,ebx // копируем результат
   pop ebx
end;

//Максимальное количество ядер у процессора
function GetMaxCpuId : Longword;register;
  asm  //EAX, EDX, ECX - Универсальные регистры можно смело их использовать
   push ebx  // а вот EBX надо бы сохранить
   mov eax,1 // режим работы cpuid
   cpuid
   shr ebx, 16 // сдвигаем впрво
   and ebx, $f // маскируем
   mov eax,ebx // копируем результат
   pop ebx
end;


26-04-2007 10:10
aiva:

А в каком хелпе вы это нашли? Вот официальный хелп - http://msdn2.microsoft.com/en-us/library/ms644904.aspx
Ничего подобного я в нём не вижу.


26-04-2007 08:29
Вопрос к Сергею по-поводу QueryPerformanceCounter.
В хелпе подчеркивается, что этот счетчик реализован не во всех архитектурах ПК. Нет ли у Вас сведений о том в каких архитектурах его нет ?
 aiva


20-10-2006 16:41
From Wikipedia, the free encyclopedia:


In the X86 assembly language, the RDTSC instruction is a mnemonic for Read Time Stamp Counter. The instruction returns a 64 bit value in registers EDX:EAX the count of ticks from processor reset. Added in Pentium. Opcode: 0F 31.

The RDTSC instruction has until recently been an excellent, high-resolution, low-overhead way of gettting CPU timing information. Or at least it has been, until the advent of multi-core, hibernating CPU's, and multiple processors. The issue has two components - rate of tick, and do all cores (processors) have identical values in their timekeeping registers. At least under Windows, there is no longer any promise that several CPU's on one motherboard will have time stamp counters in sync. So you can no longer get reliable time stamp values unless you lock your program to use just one CPU. Even then, the CPU speed may change due to power-saving measures taken by the OS or BIOS.

Under Windows platforms, Microsoft strongly discourages using RDTSC for high-resolution timing for exactly these reasons, providing instead the QueryPerformanceCounter and QueryPerformanceFrequency Windows APIs.


16-06-2005 09:38
Господа! Я уже давно нарисовал три функции, которые использую при определении времени работы участков кода. Выкладываю, не побрезгуйте :)

resourcestring
   _mC=' (%sмкс)';
   _min=' (nn:ss.zzz)';
   _Hour=' (hh:nn:ss)';

var FreqCPU:Double;


//OldCountCPU:           на входе - старое количество тактов процессора,
//                       а на выходе - новое количество тактов процессора
//Возвращаемое значение: Разница между старым и новым количеством тактов процессора
function CountCPU(var OldCountCPU:int64):int64;
assembler; asm
push  eBx
push  eCx
push  eSi
mov   eSi,eAx

db $0F;          //eAx - младшая часть eDx - старшая часть
db $31;

mov   eCx,Ds:[eSi]
mov   eBx,Ds:[eSi+4]
mov   Ds:[eSi],eAx
mov   Ds:[eSi+4],eDx

sub   eAx,eCx
sbb   eDx,eBx
mov   eCx,49
xor   eBx,eBx
sub   eAx,eCx
sbb   eDx,eBx
pop   eSi
pop   eCx
pop   eBx
end;

//Устанавливаем тактовую частоту процессора в Мгц
//Delay:                  Задершка в мC для расчета частоты процессора
procedure InitFreqCPU(Delay:DWORD=440);
var N:DWORD;
     T,NN:int64;
  begin
   N:=GetTickCount;
   while N=GetTickCount do;
   CountCPU(T);
   N:=GetTickCount;
   while N>GetTickCount-Delay do;
   //Sleep(Delay);
   NN:=CountCPU(T);
   NN:=(NN+Delay*500)div(Delay*1000);
   FreqCPU:=NN;
  end;

//CountCPU:              Количество тактов процессора
//Возвращаемое значение: Текстовая строка содержащая время
function CountCPUtoSTR(CountCPU:Int64):string;
var T:TDateTime;
    TT:Double;
    TS:string;
begin
if (FreqCPU<>0) then begin
  T:=CountCPU;
  T:=T/(FreqCPU);
  if T<2000 then TS:=Format(_mC,[inttostr(Round(T))])
    else begin
     TT:=T/1000000;
     if TT<3000 then DateTimeToString(TS,_min,TT/86400)
                else DateTimeToString(TS,_Hour,TT/86400)
   end;
  result:=TS;
end else result:='FreqCPU=0';
end;

 Cep


06-01-2004 14:32
В ответ на сообщение от Гаврилы:
если точность +/- 1 мс - пожалуйста функции API SetTimer().

Через API SetTimer достичь точности +/- 1 мс невозможно в принципе.


10-02-2003 15:06
Господа, к чему эти наезды?
Если вам нужно засекать интервалы с точностью +/- 55 мс, пользуйтесь
прерыванием int 8 bios под ДОС, если точность +/- 1 мс - пожалуйста функции API SetTimer(). Если же требования к измерениям - +/- 1 мкс - под Виндами действительно подойдет QueryPerformanceCounter(), но на таких скоростях многозадачности лучше избегать, поэтому можно читать порт 43h таймера, изменяющийся с частотой 1.19 МГц.
И, наконец, когда требуемая точность фантастическая (+/- 1 нс), не остается ничего, кроме RDTSC, которая на 1700 МГц будет регистрировать 1700 тиков в мкс, или 0,6 нс/тик


09-04-2002 00:54
По моему вы развели бодягу. Почитайте WIN SDK.

LARGE_INTEGER COUNT;
QueryPerformanceCounter(&COUNT);// количество тиков с момента запуска
QueryPerformanceFrequency(&COUNT);// частота счетчика типовая 1,19 MHZ

Вполне достаточно для точных измерений.


04-03-2002 22:13
Эта 'одна толстая книга' - Delphi 3. Библитека программиста by Д.Тейлор, Дж.Мишель,... 'Питер  Ком', СПБ, 1998. Начиная с D4 доступна более удобная форма:
function  RDTSC: int64; assembler;
asm
  db $0F,$31   // RDTSC
end;

var
  Temp: int64;
...
Temp := RDTSC;
... // код, который надо померить на быстродействие
ShowMessage( IntToStr( RDTSC - Temp ) );

вот мы и получили количество тактов процессора на участок кода
если разделить на тактовую частоту процессора можно получить примерную продолжительность выполнения (наиболее точную) блока кода.
Примерную потому, что процессор может в промежутке решить занятся своими или еще какими делами. Конечно можно временно повысить приоритет процесса, но требует определнной возни. Некоторые могут предложить прокрутить неколько проходов блока между вызовами RDTSC  для 'накопления статистики' точности, но тут можно столкнуться с тем, что блок кода и/или данных эффективно закэшируется и вы получите отличные :) резльтаты по быстродействию, сильно отличающиеся от реальности (в разы).
Вызов API-шных функций потребует больщих сил. А обычно достаточно оценить время выполнения с наименьшими затартами на набор отладочного текста.


18-09-2001 09:59
Предыдущий свой постинг я было думал как дополнение к статье оформить, но времени нет. Если Королева захочет - пусть с этим текстом поступит как хочет


18-09-2001 09:57
Дополнение материала:

Начало мироздания (WinNT3.1, W95):
===================================
DWORD GetTickCount(VOID);

Возвращаемое значение:
Возвращается число миллисекунд прошедших с начала старта системы

Примечане:
Истекшее время сохраняется в типе DWORD (4b).
Поэтому время обнуляется, если система работает непрерывно 49.7 дней.

Мысли:
Высокая точность этой функции вызывает сомнения

Высокие технологии:
====================
Function  ReadTimeStampCounter: Int64;
Asm
  db $0F,$31 //RDTSC
End;//

Возвращаемое значение:
Загружает текущее значение процессорного time-stamp счетчика в регистры edx:eax. Счетчик хранится в 64битном регистре MSR.

Правильный (на мой взгляд ;-) способ:
======================================
Функция GetThreadTimes возвращает временную информациюдля заданного потока.

BOOL GetThreadTimes(
  HANDLE hThread,             // handle to thread
  LPFILETIME lpCreationTime,  // время создания потока
  LPFILETIME lpExitTime,      // время завершения потока
  LPFILETIME lpKernelTime,    // thread kernel-mode time
  LPFILETIME lpUserTime       // thread user-mode time - ВОТ ОНО! Сколько работал наш код
);

Упарился переводить ;-)
Тут и так всё понятно - получаем чистое время работы профилируемого кода, без помех вносимых другими потоками (в тч системными)
Сообщение не подписано


17-09-2001 15:22
Вообще-то это давно известная инструкция...
Замечания.  

1. Используй Int64 - и все будет ок, тем паче что для Int64 есть перегруженные IntToStr.

У меня эта функция выглядит так:
function GetClock:Int64;
asm
        DB 0Fh
        DB 31h
end;

2. Учти - что не получится таким образом измерить скорость задачи в многозадачной системе




17-09-2001 11:53
Третья часть (конец)
----------------
Одна из проблем, с которой вы столкнетесь при использовании команды RDTSC,
заключается в том, что функции IntToStr и Format("%d") могут работать только
со значениями типа LongInt, а не comp. Если этим функциям передается
значение
типа comp, оно не может превышать High(LongInt), то есть 2147483647.
Возможно,
эти цифры производят впечатление, если они определяют сумму в долларах, но
на
Pentium с тактовой частотой 133 МГц это соответствует всего лишь 16
секундам.
Если вам потребуется сравнить время работы двух длительных процессов,
разность
между показаниями таймера в начале и конце работы легко может превысить
High(LongInt).

Проблема решается просто. Хотя тип comp соответствует 64-битному целому, на
самом деле это тип данных сопроцессора 80х87. Чтобы отформатировать comp
функцией Format(), необходимо воспользоваться форматами с плавающей точкой.
Функция CompToStr в листинге 9.4 скрывает все хлопотные подробности, причем
с ней сгенерированный компилятором объектный код получается более
компактным,
нежели при непосредственном использовании нескольких вызовов Format().

Листинг 9.4. COMP2STR.SRC

function CompToStr(N: comp): string;
begin
  Result := Format("%.0n", [N]);
end;
Напоследок скажу лишь следующее. Потребность в измерении временных
интервалов
сейчас возникает намного реже, чем в былые времена. В то же время с
появлением
команды RDTSC такое измерение становится удобным и надежным.

На этом замечании я передаю повествование своему соавтору, Эду Джордану.
Продолжай, Эд
--
Отправлено через сервер Talk.Ru - http://www.talk.ru
----------------------------------------------------------------------  




Сообщение не подписано


17-09-2001 11:52
---------
Вторая часть:
Вот кусок из книги:

Использование RDTSC для измерения временных интервалов на Pentium
В доисторическую эпоху написание быстрых программ не сводилось к правильному
выбору алгоритма; программисту приходилось помнить временные
характеристики различных команд и измерять время выполнения различных
вариантов. Поскольку системный таймер <тикает> лишь каждые 55 миллисекунд,
при измерениях приходилось повторять одни и те же вычисления сотни тысяч
раз или же пускаться на хакерские ухищрения вроде чтения внутренних
регистров таймера, чтобы получить значение времени с точностью до 838
наносекунд.

В наши дни появились хорошие компиляторы и быстрые процессоры, в результате
чего стало довольно трудно написать какой-нибудь <предельно тупой> код,
существенно замедляющий работу программы. Однако по иронии судьбы средство
для измерения временных интервалов появилось лишь в процессоре Pentium.
Команда RDTSC (Read Time Stamp Counter) возвращает количество тактов,
прошедших с момента подачи напряжения или сброса процессора.
Где была эта
команда, когда мы действительно нуждались в ней?

И все же лучше поздно, чем никогда. Команда RDTSC состоит из двух байтов:
$0F 31. Она возвращает в регистрах EDX:EAX 64-битное значение счетчика.
Поскольку сопроцессорный тип данных comp представляет собой 64-битное целое,
мы можем прочитать текущее значение с помощью кода Delphi, приведенного в
листинге 9.3.

Листинг 9.3. RDTSC.SRC

const
   D32 = $66;

function RDTSC: comp;
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;
-----------
Конец второй части
Сообщение не подписано


17-09-2001 11:51
Прикол конечно!
Смотрю, кто то уже от моего имени статьи отправляет, с моими постингами в фидошные конфы. Хотел уже письмо королеве написать что бы подпись сменили, т.к. тоже Шевченко В.В., но подписываюсь AWS Владимир.

Т.к. точно такой же постинг посылал в fido7.delphi аж в июне.
Я ничего не имею против плагиата, тем более не я же автор оригинала :)

Прикольно конечно, тем более вероятно, что Шевченко В.В. (с Украины) может и не подписан на фидо, но я хотел все же бросить то письмо в оригинале.


И еще.
Если такие статьи тянут на то, что бы их в сокровищницу ставили, то наверно стоит брать информацию из фидошных конф. Т.к. эта инфа в общем то рядовая.
Вот и само письмо из фидо:
-------------------------------------------
От:AWS Vladimir (aws@asbest.ru)
Заголовок:Re: На: Timer <1ms
Группы новостей:fido7.ru.delphi
View: Complete Thread (4 articles) | Original Format
Число:2001-06-01 00:58:26 PST

(снова я на работе:)

>> вызвал инструкцию RDTSC, запомнил счетчик, а прежде чем ты вызвал ее
>> повторно Windows передала управление другому процессу, который съел
>> n-е количество времени.
>
>Про это и говорю.

При чем сдесь процессы, если выдются такты проца?

Команда RDTSC (Read Time Stamp Counter) возвращает количество тактов,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
прошедших с момента подачи напряжения или сброса процессора.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Конец первой части:
(т.к превышение 5К)
Сообщение не подписано


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Два кольца, два конца, посередине гвоздик.
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.

Оценка содержания
 
Содержит полезные и(или) интересные сведения
 
Ничего особенно нового и интересного
 
Написано неверно (обязательно укажите почему)


Оценка стиля изложения
 
Все понятно, материал читается легко
 
Есть неясности в изложении
 
Непонятно написано, трудно читается

Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве
      
    Время на сайте: GMT минус 5 часов

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

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования