Форум по 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,093
Версия 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). Особенность моего задания именно в том, что мне нужно получать временные задержки основываясь именно на частоте процессора. Чем больше частота, тем выше точность задржки. Вот в чем суть! Надесь, что сейчас вопрос более понятен.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#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)
    {
<b>      ExactTimer exactTimer = *((ExactTimer*)pExactTimer);
      LARGE_INTEGER liFrequency, liStartTime, liCurrent;
      QueryPerformanceFrequency(&liFrequency);
      __int64 llWaitTime = ((liFrequency.QuadPart / 1000) * exactTimer.Milliseconds);
      while (true)
</b>     
{
        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,093
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от falabella
Просьба немного изменилась.
Вот код. Его надо адаптировать под делфи, а выделенную части надо переделать на получение не просто тика, а на зависимость от частоты процессора (т,е. t = 1/f, f - количество тиков в секунду, частоту получить через rdtsc). Особенность моего задания именно в том, что мне нужно получать временные задержки основываясь именно на частоте процессора. Чем больше частота, тем выше точность задржки. Вот в чем суть! Надесь, что сейчас вопрос более понятен.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#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)
    {
<b>      ExactTimer exactTimer = *((ExactTimer*)pExactTimer);
      LARGE_INTEGER liFrequency, liStartTime, liCurrent;
      QueryPerformanceFrequency(&liFrequency);
      __int64 llWaitTime = ((liFrequency.QuadPart / 1000) * exactTimer.Milliseconds);
      while (true)
</b>     
{
        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, остальное - шелуха вокруг. Собственно, как я понимаю, эта функция запускается как отдельный поток. Фактически,она и выполняет расчет времени ожидания в зависимости от частоты проца.

Т.е. тело потока будет выглядеть как-то так:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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, время: 05:24.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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