Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 25.04.2008, 14:58
falabella falabella вне форума
Прохожий
 
Регистрация: 25.04.2008
Сообщения: 4
Репутация: 10
По умолчанию Системный таймер и частота процессора

Всем привет. На носу диплом.. в процессе разработки зашла в тупик. у меня есть функция для определения тактовой частоты процессора. Нужно с помощью нее получать конкретные временные зедержки (привязку нужно сделать через системный таймер). Не могу придумать как это реализовать. Частота получается с помощью RdtSC(если нужно взглянуть на функцию, могу выложить исходник). Очень надеюсь на вашу помощь..
Ответить с цитированием
  #2  
Старый 25.04.2008, 16:03
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,036
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А нужно делать именно так?
А может сделать протой поток с приоритетом, где в цикле крутить sleep(n) и поднятие соотв. события/выброс сообщения? Точность будет вполне приемлемая для обычных задач (не realtime)
Ответить с цитированием
  #3  
Старый 25.04.2008, 16:14
falabella falabella вне форума
Прохожий
 
Регистрация: 25.04.2008
Сообщения: 4
Репутация: 10
По умолчанию

нужно именно так. чтобы создать аппаратнонезависимый способ точных замеров. не я придумала тему диплома)
Ответить с цитированием
  #4  
Старый 28.04.2008, 12:00
AlexSku AlexSku вне форума
Специалист
 
Регистрация: 07.05.2007
Адрес: Москва
Сообщения: 884
Репутация: 21699
По умолчанию

Чтобы делать временные задержки через системный таймер, скорее всего частоту процессора знать не надо, т.к. обращение к системному таймеру это вызов процедуры операционной системы, а ОС навряд ли будет требовать от вас привязку к железу.
Ответить с цитированием
  #5  
Старый 28.04.2008, 13:47
falabella falabella вне форума
Прохожий
 
Регистрация: 25.04.2008
Сообщения: 4
Репутация: 10
По умолчанию

Просьба немного изменилась.
Вот код. Его надо адаптировать под делфи, а выделенную части надо переделать на получение не просто тика, а на зависимость от частоты процессора (т,е. t = 1/f, f - количество тиков в секунду, частоту получить через rdtsc). Особенность моего задания именно в том, что мне нужно получать временные задержки основываясь именно на частоте процессора. Чем больше частота, тем выше точность задржки. Вот в чем суть! Надесь, что сейчас вопрос более понятен.
Код:
#include <windows.h> 
#include <iostream> 
#include <conio.h> 

using namespace std; 

class ExactTimer 
{ 
public: 
    typedef void (*CallbackProc)(void); 

    ExactTimer() 
    { 
      Callback = NULL; 
      StartThreadHandle = NULL; 
      RepeatOnce = false; 
      Milliseconds = 1000; 
    } 
    
    ~ExactTimer() 
    { 
      Stop(); 
    } 

    void Start() 
    { 
      Stop(); 
      StartThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(StartThread),(void*)this,NULL,0); 
    } 

    void Stop() 
    { 
      if (StartThreadHandle != NULL) 
      { 
        TerminateThread(StartThreadHandle, 0); 
        CloseHandle(StartThreadHandle); 
        StartThreadHandle = NULL; 
      } 
    } 
    
    void SetMilliseconds(long milliseconds) 
    { 
      Milliseconds = milliseconds; 
    } 

    long GetMilliseconds() const 
    { 
      return Milliseconds; 
    } 

    void SetCallbackProcedure(CallbackProc callback) 
    { 
      Callback = callback; 
    } 

    void SetRepeatOnce(bool repeatOnce) 
    { 
      RepeatOnce = repeatOnce; 
    } 
protected: 
    CallbackProc Callback; 
    bool RepeatOnce; 
    bool Repeat; 
    long Milliseconds; 
    HANDLE StartThreadHandle; 

    static DWORD WINAPI StartThread(void *pExactTimer) 
    { 
      ExactTimer exactTimer = *((ExactTimer*)pExactTimer); 
      LARGE_INTEGER liFrequency, liStartTime, liCurrent; 
      QueryPerformanceFrequency(&liFrequency); 
      __int64 llWaitTime = ((liFrequency.QuadPart / 1000) * exactTimer.Milliseconds); 
      while (true) 
      
{ 
        QueryPerformanceCounter(&liStartTime); 
        QueryPerformanceCounter(&liCurrent); 
        while ((liCurrent.QuadPart - liStartTime.QuadPart) < llWaitTime) 
          QueryPerformanceCounter(&liCurrent); 
        if (exactTimer.Callback != NULL) 
          exactTimer.Callback(); 
        if (exactTimer.RepeatOnce) 
          exactTimer.Stop(); 
      } 
      return 0; 
    }  
}; 

void PrintTheEnd() 
{ 
  cout << " THE END " << endl; 
} 

int main() 
{ 
  ExactTimer t; 
  t.SetRepeatOnce(false); 
  t.SetMilliseconds(100); 
  t.SetCallbackProcedure(PrintTheEnd); 
  t.Start(); 
  _getch(); 
  t.Stop(); 
  _getch(); 
  return 0; 
}
Ответить с цитированием
  #6  
Старый 28.04.2008, 16:32
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,036
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от falabella
Просьба немного изменилась.
Вот код. Его надо адаптировать под делфи, а выделенную части надо переделать на получение не просто тика, а на зависимость от частоты процессора (т,е. t = 1/f, f - количество тиков в секунду, частоту получить через rdtsc). Особенность моего задания именно в том, что мне нужно получать временные задержки основываясь именно на частоте процессора. Чем больше частота, тем выше точность задржки. Вот в чем суть! Надесь, что сейчас вопрос более понятен.
Код:
#include <windows.h> 
#include <iostream> 
#include <conio.h> 

using namespace std; 

class ExactTimer 
{ 
public: 
    typedef void (*CallbackProc)(void); 

    ExactTimer() 
    { 
      Callback = NULL; 
      StartThreadHandle = NULL; 
      RepeatOnce = false; 
      Milliseconds = 1000; 
    } 
    
    ~ExactTimer() 
    { 
      Stop(); 
    } 

    void Start() 
    { 
      Stop(); 
      StartThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(StartThread),(void*)this,NULL,0); 
    } 

    void Stop() 
    { 
      if (StartThreadHandle != NULL) 
      { 
        TerminateThread(StartThreadHandle, 0); 
        CloseHandle(StartThreadHandle); 
        StartThreadHandle = NULL; 
      } 
    } 
    
    void SetMilliseconds(long milliseconds) 
    { 
      Milliseconds = milliseconds; 
    } 

    long GetMilliseconds() const 
    { 
      return Milliseconds; 
    } 

    void SetCallbackProcedure(CallbackProc callback) 
    { 
      Callback = callback; 
    } 

    void SetRepeatOnce(bool repeatOnce) 
    { 
      RepeatOnce = repeatOnce; 
    } 
protected: 
    CallbackProc Callback; 
    bool RepeatOnce; 
    bool Repeat; 
    long Milliseconds; 
    HANDLE StartThreadHandle; 

    static DWORD WINAPI StartThread(void *pExactTimer) 
    { 
      ExactTimer exactTimer = *((ExactTimer*)pExactTimer); 
      LARGE_INTEGER liFrequency, liStartTime, liCurrent; 
      QueryPerformanceFrequency(&liFrequency); 
      __int64 llWaitTime = ((liFrequency.QuadPart / 1000) * exactTimer.Milliseconds); 
      while (true) 
      
{ 
        QueryPerformanceCounter(&liStartTime); 
        QueryPerformanceCounter(&liCurrent); 
        while ((liCurrent.QuadPart - liStartTime.QuadPart) < llWaitTime) 
          QueryPerformanceCounter(&liCurrent); 
        if (exactTimer.Callback != NULL) 
          exactTimer.Callback(); 
        if (exactTimer.RepeatOnce) 
          exactTimer.Stop(); 
      } 
      return 0; 
    }  
}; 

void PrintTheEnd() 
{ 
  cout << " THE END " << endl; 
} 

int main() 
{ 
  ExactTimer t; 
  t.SetRepeatOnce(false); 
  t.SetMilliseconds(100); 
  t.SetCallbackProcedure(PrintTheEnd); 
  t.Start(); 
  _getch(); 
  t.Stop(); 
  _getch(); 
  return 0; 
}

Ну, собственно, весь интересный код лежит в функции ExactTimer exactTimer, остальное - шелуха вокруг. Собственно, как я понимаю, эта функция запускается как отдельный поток. Фактически,она и выполняет расчет времени ожидания в зависимости от частоты проца.

Т.е. тело потока будет выглядеть как-то так:
Код:
var
  AWaitTime : Int64;
  ACurTime, AStartTime : Int64;
  CPUFrq : Int64;
begin
  QueryPerformanceFrequency(CPUFreq);
  AWaitTime := CPUFreq / 1000 * Miliseconds;
  QueryPerformanceCounter(AStartTime);
  QueryPerformanceCounter(ACurTime);
  While Not Terminated Do
    Begin
      If (ACurTime - AStartTime) > AWaitTime Then
        Begin
          AStartTime := ACurTime;
          If Assigned(FCallBack) Then FCallBack;
        End;
      QueryPerformanceCounter(ACurTime);
    End;
end;
Ответить с цитированием
  #7  
Старый 28.04.2008, 17:26
falabella falabella вне форума
Прохожий
 
Регистрация: 25.04.2008
Сообщения: 4
Репутация: 10
По умолчанию

Спасибо! но вопросы еще будут...
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 04:23.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter