Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Событие WM_TIMER, Ускорить работу таймера 
:(
    Опции темы
decembrist
  Дата 1.7.2004, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 1.4.2004

Репутация: нет
Всего: нет



Столкнулся с проблемой на SetTimer-е. Период в милисекундах необходимо установить от 1 до 3 мс. Когда я пишу SetTimer(1,1,0); или SetTimer(1,3,0); у меня программа работает с той же скоростью что и при SetTimer(1,10,0); (при 10 мс) Что 10 мс минимальное значение? Можно как- нибудь ускорить работу программы? wow.gif
PM MAIL   Вверх
Конструктор
Дата 1.7.2004, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 641
Регистрация: 12.5.2004
Где: Москва

Репутация: нет
Всего: 10



Дык по идее по таймерам всегда и пишут, что они неточные. А на таких маленьких интервалах и подавно. Вот секунды они могут более менее отработать, а миллисекунды. У винды наверное кванты времени для процессов и то больше.

PM MAIL WWW ICQ   Вверх
Олег М
Дата 1.7.2004, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Есть ещё мультимедиа-таймеры посмотри подробнее в МСДН или
http://msdn.microsoft.com/library/default...._resolution.asp
PM MAIL ICQ   Вверх
decembrist
Дата 1.7.2004, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 1.4.2004

Репутация: нет
Всего: нет



А как мне тогда скорость увеличить?
Добавлено @ 13:26
Таймеры посмотрел - не получается
PM MAIL   Вверх
gepard
Дата 1.7.2004, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2477
Регистрация: 29.2.2004

Репутация: 2
Всего: 40



Я не понял, тебе надо отследить период в 3 милисекунды?


--------------------
Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным!
© Я, Берсерк, что значит - Неистовый. 
PM MAIL WWW ICQ   Вверх
decembrist
Дата 1.7.2004, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 1.4.2004

Репутация: нет
Всего: нет



Да.
PM MAIL   Вверх
Олег М
Дата 1.7.2004, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Сделай в отдельном потоке безо всяких таймеров. Там не будет тормозить


PM MAIL ICQ   Вверх
decembrist
Дата 1.7.2004, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 1.4.2004

Репутация: нет
Всего: нет



Я новичок никогда потоков не создавал Как это делается sad.gif
PM MAIL   Вверх
Олег М
Дата 1.7.2004, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



А тебе что конкретно нужно сделать?
PM MAIL ICQ   Вверх
chipset
Дата 1.7.2004, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 164



Да не... Вряд ли что то получится, Windows система нереального времени sad.gif
Так что переходим на линух, все... biggrin.gif


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Олег М
Дата 1.7.2004, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Цитата
Да не... Вряд ли что то получится, Windows система нереального времени
Так что переходим на линух, все... 

В виндах тоже всё прекрасно работает. Непонятно только причём здесь реальное время и с какой радости линух стал системой реального времени?

PM MAIL ICQ   Вверх
chipset
Дата 1.7.2004, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 164



Да но такие маалюююсенькие периоды времени стандартными средствами отследить не получится, если вообще получится...
Может я ошибаюсь? withstupid.gif


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Олег М
Дата 1.7.2004, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Цитата
Да но такие маалюююсенькие периоды времени стандартными средствами отследить не получится, если вообще получится...
Может я ошибаюсь?

Ошибаешься. Я сейчас точно не вспомню, там где-то есть таймеры высокого разрешения и даже, по-моему потоки можно останавливать на время меньше 1 мс. Когда-то интересовался - потом забыл.

PM MAIL ICQ   Вверх
gepard
Дата 1.7.2004, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2477
Регистрация: 29.2.2004

Репутация: 2
Всего: 40



Код

#include <sys/timeb.h>
#include <time.h>
void main()
{
   struct __timeb64 tim;
   _ftime64(&tim);
   double time_need=time(0)+tim.millisec/1000.0f;
   double now_time;
   while(true)
   {
       _ftime64(&tim);
       now_time=time(0)+tim.millisec/1000.0f;
       if ((now_time-time_need)==0.003f)
       {
            printf("My Congratulations!\n");
            break;
       }
   }
}

Я вот только не помню .millisec ли он называется(аргумент сруктуры) hmmm.gif
Ещё нужна версия time.h и timeb.h не старая(у меня в VC++ 6.0: timeb - нету, а time - старая).
В VC++ .NET(2002) точно всё есть.


--------------------
Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным!
© Я, Берсерк, что значит - Неистовый. 
PM MAIL WWW ICQ   Вверх
bel_nikita
  Дата 1.7.2004, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



GetTickCount() - нам поможет biggrin.gif
Цитата
Да не... Вряд ли что то получится, Windows система нереального времени
Ну и че из этого. Я под RTOS "сижу". То же не гарантируется <3 мсек tounge.gif . Хотя конечно и пишут, что все намази и т.д. и т.п. А на практике совсем подругому sad.gif . Потом зависит, как запрограммирован таймер. Если конечно через таймер работают. Не знаю, как винда устроена. В общем че писать. Попробывать написать свой таймер через GetTickCount().


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Дрон
Дата 1.7.2004, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



gepard
Да, эта функция есть только в VC++ .NET. И точность у неё около 16мс.
GetTickCount() тоже даёт точность только ~16мс exclamation.gif
Можете проверить сами, записывая в файл в цикле значения, полученные из этих функций.

Я уже с этим не раз сталкивался -- в Windows ничего особо толкового не получится.
Миллион раз уже тут писал, что нужно пользоваться QueryPerformanceCounter -- поищите по форуму.

Самый примитивный способ, использующий эту функцию:
Цитата
    LARGE_INTEGER interval,start,now;
    QueryPerformanceFrequency(&interval);
    interval.QuadPart *= 0.003;

    QueryPerformanceCounter(&start);
    do{
          QueryPerformanceCounter(&now);
    }while (now.QuadPart - start.QuadPart <= interval.QuadPart);

Цикл закончится, когда пройдёт интервал в 0.003 секунды -- с точностью до скорости выполнения команды.
Недостаток -- грузит проц на 100% для больших интервалов.

Это сообщение отредактировал(а) Дрон - 2.7.2004, 05:46


--------------------
Да. Именно так.
PM   Вверх
bel_nikita
  Дата 1.7.2004, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Цитата
GetTickCount() тоже даёт точность только ~16мс
Можете проверить сами, записывая в файл в цикле значения, полученные из этих функций

запись в файл не показатель. В цикле писать в файл и потом удивляться, что GetTickCount() выдает сумашедшие результаты . Оригинально biggrin.gif . ~16мс, грубо говоря, в таком случае, получается время записи в файл не считая thread'ы и т.п. Вообще-то GetTickCount() даёт точность 1мс biggrin.gif .

В винде, как знаю еще есть CreateWaitableTimer. Только не знаю она его в нулевой интерапт встраивает или нет. И как запрограммирован таймер в винде?

Это сообщение отредактировал(а) bel_nikita - 2.7.2004, 00:04


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Дрон
Дата 2.7.2004, 01:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



bel_nikita
Ты не правильно меня понял smile.gif
Результаты записи в файл были примерно такие:
Цитата
0
0
0
... и так несколько сотен раз
15
15
15
... и так несколько сотен раз
30
30
30
... и так несколько сотен раз

За эти 15мс прога успевала записать строку в файл "несколько сотен раз" smile.gif

Если не веришь, то вот другой простой тест:
Цитата
#include <windows.h>
#include <stdio.h>
#include <math.h>

#define ARRSIZE 2000 // не более 2х секунд, иначе нужно увеличить

void main()
{
    float z = 1233;
    const N = 100000;
    int vals[ARRSIZE];
    int i,k;
    ZeroMemory(vals,sizeof(int)*ARRSIZE);
    for(k=0;k<100;k++){
          DWORD start = GetTickCount();
          for(i=0; i<N; i++)
          {
              z = exp(log(z));
          }
          DWORD finish = GetTickCount();
          vals[finish-start]++;
    }
    FILE *fp = fopen("results.txt","wt");
    for(i=0;i<ARRSIZE;i++)
    {
          if(vals[i]!=0) fprintf(fp,"%i мс: %i%%\n",i,vals[i]);
    }
    fclose(fp);
}

Тут зависит от быстродействия компа. Уменя Athlon XP 2500+.
Результаты
При N = 100000 - 15 мс: 24%, 16 мс: 35%, 31 мс: 29%, 32 мс: 12%
При N = 50000 - 0 мс: 29%, 15 мс: 26%, 16 мс: 45%
При N = 25000 - 0 мс: 64%, 15 мс: 14%, 16 мс: 22%
Я знал, что AMD делает крутые процессоры, но то что они в 64% случаях могут вычислить 25000 сложных математических операций вообще не потратив на это времени -- это уже действительно круто! smile.gif smile.gif smile.gif

WaitableTimer может быть и полезен. Как и Sleep smile.gif
Только на любой из методов будут очень сильно влиять другие процессы и потоки.

ЗЫ: Подсветка синтаксиса моя -- экспериментальная smile.gif

Это сообщение отредактировал(а) Дрон - 2.7.2004, 05:48


--------------------
Да. Именно так.
PM   Вверх
bel_nikita
Дата 2.7.2004, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Дрон - это совсем не то. Это замер времени выполнения. Причем грубый и не отражающий реальное быстродействие процессора. А не задумывались, сколько раз во время цикла происходят переключения на другие thread'ы?. Что-то я отвлекся smile.gif Надо-то ведь таймер.



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
kruchinin
Дата 2.7.2004, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 19.4.2003

Репутация: нет
Всего: нет



Почитайте обычный help Borlandа 5.0
Стандартные функции
GetTickCount
или
QueryPerformanceCounter, QueryPerformanceFrequency

я не понимаю какие могут быть проблемы - эти функции работают с частотой процессора.

PM MAIL   Вверх
bel_nikita
Дата 2.7.2004, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



kruchinin
Цитата
я не понимаю какие могут быть проблемы - эти функции работают с частотой процессора
проблема реализовать таймер с частотой <3ms wink.gif biggrin.gif
Цитата
Почитайте обычный help Borlandа 5.0

Мы люди темные. Help'ы к борланду не читали.
Если у вас все так просто, привидите пожалуйста пример реализации таймера под Виндой, который будет срабатывать менее чем 3мсек biggrin.gif


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Олег М
Дата 2.7.2004, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Цитата
Мы люди темные. Help'ы к борланду не читали.

А как насчёт мсдн?
Цитата
Если у вас все так просто, привидите пожалуйста пример реализации таймера под Виндой, который будет срабатывать менее чем 3мсек 

К сожалению пока не могу, но так, теоретически, по моему в виндах процессы переключаются намного чаще чем раз в 1 мс. Почему бы нет?

PM MAIL ICQ   Вверх
kruchinin
Дата 2.7.2004, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 19.4.2003

Репутация: нет
Всего: нет



Вот код из моей игры Танки 3:
system_a=true;//переменная для выхода из системы
// в игре я не посылаю сообщение WM_QUIT, а просто меняю переменную
freg1=GetTickCount();
for_fps=0;//вычисление FPS
tick=false;//произошло ли событие таймера
while (true)
{
//обработка сообщений
if (PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
{
if (Msg.message == WM_QUIT)
break;
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
else ;
//вызов таймера
if (system_a)
{
if (tick) {//если нужное время прошли - рисуем картинки
None(hWnd);
tick=false;
}
freg2=GetTickCount();
if (freg2-freg1>1000/_TIMER_)
{//определяем нужное время _TIMER_ - задать это время
tick=true;
for(i=freg2-freg1;i>1000/_TIMER_;i-=1000/_TIMER_)
{
for(j=0;j<_TIMER_-1;j++) fps_a[j]=fps_a[j+1];
fps_a[_TIMER_-1]=for_fps;//ну это не важно просто для измерения FPS в игре
for_fps=0;
fps=0;
for(j=0;j<_TIMER_;j++) fps+=fps_a[j];
OnTimer(hWnd);//вызываем событие таймера
}
freg1=GetTickCount()-i;
//выход из игры
if (Exit_Game) PostMessage(hWnd,WM_DESTROY,0,0);
}
}
}

PM MAIL   Вверх
Олег М
Дата 2.7.2004, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Танки - это круто adv/64.gif
PM MAIL ICQ   Вверх
Дрон
Дата 2.7.2004, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



Цитата
Дрон - это совсем не то. Это замер времени выполнения. Причем грубый и не отражающий реальное быстродействие процессора.
Да я тут не быстродействие меряю! А показываю, что функция GetTickCount() имеет предел точности в 16мс!!!!

Ну ладно. Забили smile.gif
Раз нужен таймер -- получайте (работает только в Windows NT/2K/XP, т.к. в 95/98/Me нет функции CreateWaitableTimer()):
Цитата
#define _WIN32_WINNT 0x0400
#include <windows.h>

#include <stdio.h>
#include <conio.h>

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

class WaitableTimer{
    HANDLE hTerminationEvent; // сигнал к завершению потока
    HANDLE hThread; // хэндл потока с таймером
    int  nPeriod; // период таймера
    void (APIENTRY *pRoutine)(LPVOID,DWORD,DWORD); // функция, вызываемая по таймеру
    static DWORD WINAPI TimerThread(LPVOID Param); // функция потока
public:
    // конструктор: nMillisec - период таймера, pTimerRoutine - указатель на вызываемую функцию
    WaitableTimer(int nMillisec, void (APIENTRY *pTimerRoutine)(LPVOID,DWORD,DWORD));
    ~WaitableTimer();
    void Stop()  { SuspendThread(hThread); } // приостанавливает таймер
    void Start() { ResumeThread(hThread)} // запускает таймер
};

WaitableTimer::WaitableTimer(int nMillisec, void (APIENTRY *pTimerRoutine)(LPVOID,DWORD,DWORD))
{
    DWORD Id;
    nPeriod = nMillisec;
    pRoutine = pTimerRoutine;
    hTerminationEvent = CreateEvent(NULL,false,false,NULL);
    hThread = CreateThread(NULL,0,TimerThread,this,CREATE_SUSPENDED,&Id);
}

WaitableTimer::~WaitableTimer()
{
    SetEvent(hTerminationEvent);
    WaitForSingleObject(hThread,nPeriod);
    CloseHandle(hTerminationEvent);
    CloseHandle(hThread);
}

DWORD WINAPI WaitableTimer::TimerThread(LPVOID Param)
{
    // можно попробовать поиграть с приоритетами -- это уже на ваше усмотрение
    // SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
    WaitableTimer *obj = (WaitableTimer*)Param;
    LARGE_INTEGER DueTime;
    DueTime.QuadPart = -10000i64 * obj->nPeriod;
    HANDLE hTimer = CreateWaitableTimer(NULL,false,NULL);
    SetWaitableTimer(hTimer,&DueTime,obj->nPeriod,obj->pRoutine,obj,false);
    while (WaitForSingleObjectEx(obj->hTerminationEvent,INFINITE,true)==WAIT_IO_COMPLETION);
    CloseHandle(hTimer);
    return 0;
}

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

int i=0;
// первый параметр -- указатель на класс таймера (типа void)
void APIENTRY MyTimerRoutine(LPVOID lpArgToCompletionRoutine,
                            DWORD dwTimerLowValue,
                            DWORD dwTimerHighValue)
{
    i++;
}

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

void main()
{
    WaitableTimer Timer(4,MyTimerRoutine); // создали таймер на 4мс
    Timer.Start(); // запустили его (т.к. создаётся остановленным)
    Sleep(1000); // подождали 1 секунду
    printf("\n%i\n",i); // вывели количество запусков функции MyTimerRoutine
    getch(); // нажмите любую клавишу :-)
}
На моём компе выдаёт результат 204, вместо ожидаемых 250. А с периодом 3мс выдаёт 256, вместо 330.
Ничего более хорошего тут уже ИМХО не добиться.

Это сообщение отредактировал(а) Дрон - 2.7.2004, 17:37


--------------------
Да. Именно так.
PM   Вверх
Олег М
Дата 6.7.2004, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Цитата
На моём компе выдаёт результат 204, вместо ожидаемых 250. А с периодом 3мс выдаёт 256, вместо 330.

Ну а как ты хотел. Другим потокам-то тоже нужно время чтобы переключаться и работать - на забывай винды нифига не система реального времени. Вот и получается меньше. Вот если бы больше!!!!
А цифры такие же остаются или скачут постоянно?

PM MAIL ICQ   Вверх
Дрон
Дата 6.7.2004, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



Цитата
Ну а как ты хотел. Другим потокам-то тоже нужно время чтобы переключаться и работать - на забывай винды нифига не система реального времени.

Никак не хотел. Я всё это давно знаю smile.gif

Цифры такие же плюс-минус 1. Тяжёлых фоновых приложений не было -- иначе б скакали smile.gif


--------------------
Да. Именно так.
PM   Вверх
Олег М
Дата 6.7.2004, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Дрон
Тогда всё нормально. Надо подсчитать чистое время, которое выполняется твой поток и всё наверняка сойдётся

PM MAIL ICQ   Вверх
zss
Дата 6.7.2004, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



К примеру (а если еще это в отдельный поток - то тогда то что надо smile.gif )

Причем этот код не зависит от производительности процессора tounge.gif

Цитата

Для работы с таймером (точнее говоря, для работы с каналом 0 таймера) BIOS содержит две функции прерывания INT 1Ah. Они позволяют прочитать текущее содержимое счетчика и изменить его.

Функция 00h предназначена для чтения содержимого счетчика таймера:

На входе:      AH = 00h.

На выходе:      CX = старший байт счетчика;

                DX = младший байт счетчика;

                AL = 0, если с момента перезапуска таймера
                        прошло более 24-х часов.



Изменить содержимое счетчика таймера можно с помощью следующей функции:

На входе:      AH = 01h;

                CX = старший байт счетчика;

                DX = младший байт счетчика.

На выходе:      не используются.



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

Однако следует учитывать, что точность формирования задержки определяется частотой обновления счетчика таймера (18.2 Гц), и может оказаться недостаточной для некоторых приложений.

Мы подготовили функцию для формирования задержек с помощью таймера:

/**
*.Name        tm_delay
*.Title        Формирование задержки по таймеру
*
*.Descr        Эта функция формирует задержку, используя
*              системный таймер.
*
*.Proto        void tm_delay(int ticks)
*
*.Params      int ticks - величина задержки в тиках
*                          таймера (за одну секунду таймер
*                          тикает 18.2 раза).
*
*.Return      Ничего
*
*.Sample      tm_samp1.c
**/

#include <dos.h>
#include <conio.h>

void tm_delay(int ticks) {

        _asm {

                push si

                mov  si, ticks
                mov  ah, 0
                int  1ah

                mov  bx, dx
                add  bx, si

delay_loop:

                int  1ah
                cmp  dx, bx
                jne  delay_loop

                pop  si
        }
}



Функция использует только одно слово регистра таймера, что позволяет формировать задержки длительностью до 65536 тиков таймера. Приведенная ниже программа демонстрирует использование функции для генерации примерно десятисекундной задержки :

#include <stdio.h>
#include "sysp.h"


main() {

        printf("\nДля выполнения программной задержки примерно"
                        "\nна 10 секунд нажмите любую клавишу.");
        getch();

        printf("\n\nВремя пошло...");

        tm_delay(18 * 10);

        printf("\nГотово!");

        exit(0);
}



BIOS компьютеров IBM AT содержит еще две интересные функции для работы с таймером. Это функции 83h и 86h прерывания INT 15h.

Функция 83h позволяет запустить таймер на счет, указав адрес некоторого байта в оперативной памяти. Программа, запустившая таймер, сразу после запуска получает управление. По истечении времени, заданного при запуске таймера, функция устанавливает старший бит указанного байта в единицу, сигнализируя таким образом программе о завершении указанного временного интервала. Программа может также отменить работу таймера в этом режиме.

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

Приведем формат вызова функции 83h прерывания INT 15h:

На входе:      AH = 83h;

                AL = код подфункции:

                  0 - установить интервал, запустить таймер;
                  1 - отменить работу таймера;

                CX = старший байт времени работы счетчика,
                  задается в микросекундах;

                DX = младший байт счетчика;

                ES:BX = адрес байта, в котором по истечении
                  интервала времени старший бит будет
                  установлен в 1.

На выходе:      не используются.



Функция 86h специально предназначена для формирования задержек. Она позволяет определять время задержки в микросекундах, что достаточно удобно для многих задач. Во время выполнения задержки разрешены прерывания. Формат вызова функции:

На входе:      AH = 86h;

        CX = старший байт времени задержки,
                задается в микросекундах;

        DX = младший байт времени задержки.

На выходе:      не используются.



Это сообщение отредактировал(а) zss - 6.7.2004, 12:30
PM MAIL ICQ   Вверх
Олег М
Дата 6.7.2004, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Нифига себе! Это ещё круче танков!
PM MAIL ICQ   Вверх
decembrist
Дата 6.7.2004, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 1.4.2004

Репутация: нет
Всего: нет



Что это за ф-ция GetTickCount()?
PM MAIL   Вверх
bel_nikita
  Дата 6.7.2004, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



zss К чему это? Надо же таймер >3 мсек.

Олег М
Цитата
на забывай винда нифига не система реального времени
поясните пожалуйста, что вы понимаете под системой реального времени?

Цитата
Что это за ф-ция GetTickCount()?

проясняем функцию GetTickCount()


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
decembrist
Дата 6.7.2004, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 1.4.2004

Репутация: нет
Всего: нет



Подскажите "чайнику" как это сделать
PM MAIL   Вверх
zss
Дата 6.7.2004, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



Цитата(bel_nikita @ 6.7.2004, 15:00)
zss К чему это? Надо же таймер >3 мсек.

Это было к примеру
А если надо, то задай сколько тебе надо в tm_delay() smile.gif
PM MAIL ICQ   Вверх
Олег М
Дата 6.7.2004, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 436
Регистрация: 10.6.2004
Где: Москва

Репутация: 7
Всего: 7



Цитата
поясните пожалуйста, что вы понимаете под системой реального времени?

По моему, система реального времени - это такая система, где время выполнения любой операции жёстко определено (по максимуму).

PM MAIL ICQ   Вверх
Дрон
Дата 6.7.2004, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



zss
Цитата
А если надо, то задай сколько тебе надо в tm_delay()

Так там же минимальный интервал это 1 тик = 1/18.2 секунды = 56 мс. Многовато...

bel_nikita
Цитата
поясните пожалуйста, что вы понимаете под системой реального времени?

Вот тут можно почитать: http://www.cvalka.net/hack/read.php?file=20&dir=
Windows однозначно НЕ является операционной системой реального времени.

Добавлено @ 17:05
decembrist
А что класс WaitableTimer, приведённый мной, не подходит?


--------------------
Да. Именно так.
PM   Вверх
decembrist
Дата 7.7.2004, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 238
Регистрация: 1.4.2004

Репутация: нет
Всего: нет



Так что с таймером -то делать?
Создать поток вместо события OnTimer и как через поток его имитировать по Sleep()?
Подскажите новичку withstupid.gif
PM MAIL   Вверх
bel_nikita
Дата 7.7.2004, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Цитата
Windows однозначно НЕ является операционной системой реального времени
А вот и не правда. Смотря какая винда biggrin.gif
Вот, RTOS: Windows CE .NET, Windows XP Embedded exclamation.gif
Остальные Windows конечно же не RTOS.



--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Дрон
Дата 7.7.2004, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



bel_nikita
Ну ладно, ладно -- согласен, что и виндовоз бывает эртэос smile.gif Толку-то от этого?
И ещё, поставлю-ка я тебе "+".

decembrist
В чём именно тебе помочь? Тут уже кучу примеров привели. Что ещё нужно?
Ты умеешь потоки создавать?
Ты знаешь, как работает Sleep()?
Ты знаешь, как устроена многозадачность в Windows?
Объяснять-то много прийдётся.


--------------------
Да. Именно так.
PM   Вверх
Coocky
Дата 7.7.2004, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 2
Всего: 62



Цитата
Период в милисекундах необходимо установить от 1 до 3 мс.

Да я вообще не понимаю зачем тебе такая точность notify.gif Ты че в НАСА работаешь smile.gif В любом из предложеных тебе в вариантах ты будешь обречен на провал.Рано или поздно твой таймер даст сбой,т.к. у Винды помимо твоей проги есть еще одна важная прога-ОНА САМА.В любом случае если ЕЙ что-то нужно будет обработать,она тебя проигнорирует.Покажите мне хотя бы одну тестовую прогу по железу,которая дает точный результат sad.gif Везде все более или менее относительно.Как бы ты не хотел,ты всегда будешь работать под ВиндойНе спасут тебя потоки sad.gif



--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
bel_nikita
Дата 8.7.2004, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Coocky я думаю прав.
А если на уровень ядра спустится?
Можно конечно таймера перепрограммировать, но тогда хана всей системе.
decembrist - переходи на RTOS wink.gif
Хотя RTOS тож такую точность не гарантирует.
А для чего нужна такая точность?
Если это устройство, то может в нем есть встроенный таймер? Тогда можно запрограммировать ентот таймер на сколь хошь. Ой, что-то меня понесло smile.gif Чувствую пора спать smile.gif

На сколько точен мультимедиа таймер

З.Ы.: М-да, что-то, как-то сложно все это под виндой smile.gif

Это сообщение отредактировал(а) bel_nikita - 8.7.2004, 00:55


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Дрон
Дата 8.7.2004, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 92



Дык, Windows это ж система для домохозяек. Зачем там такие таймеры smile.gif
И на уровень ядра она тебя не очень-то пустит. Разве что драйвера попробовать писать smile.gif
decembrist
Может можно и без таймера? Какова задача-то?

ЗЫ: Вдруг окажется, что мы тут всё слишком усложняем? smile.gif


--------------------
Да. Именно так.
PM   Вверх
Leopard25
Дата 9.7.2004, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 17.4.2004

Репутация: нет
Всего: нет




http://www.proglib.ru/detail.asp?id=1169

prectimer.zip - MFC класс, реализующий очень точный таймер, использующий встроенный счетчик процессоров Pentium, который опрашивается инструкцией ассемблера RSDTC
--------------------
Обдумай, верно ли и возможно ли то, что ты обещаешь, ибо обещание - есть долг. ( Конфуций )
PM MAIL ICQ   Вверх
Гость_Алексей
Дата 22.10.2005, 07:31 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Цитата(zss @ 6.7.2004, 12:25)
К примеру (а если еще это в отдельный поток - то тогда то что надо :) )

Причем этот код не зависит от производительности процессора :p

Цитата

Для работы с таймером (точнее говоря, для работы с каналом 0 таймера) BIOS содержит две функции прерывания INT 1Ah. Они позволяют прочитать текущее содержимое счетчика и изменить его.

Функция 00h предназначена для чтения содержимого счетчика таймера:

На входе:      AH = 00h.

На выходе:      CX = старший байт счетчика;

                DX = младший байт счетчика;

                AL = 0, если с момента перезапуска таймера
                        прошло более 24-х часов.



Изменить содержимое счетчика таймера можно с помощью следующей функции:

На входе:      AH = 01h;

                CX = старший байт счетчика;

                DX = младший байт счетчика.

На выходе:      не используются.



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

Однако следует учитывать, что точность формирования задержки определяется частотой обновления счетчика таймера (18.2 Гц), и может оказаться недостаточной для некоторых приложений.

Мы подготовили функцию для формирования задержек с помощью таймера:

/**
*.Name        tm_delay
*.Title        Формирование задержки по таймеру
*
*.Descr        Эта функция формирует задержку, используя
*              системный таймер.
*
*.Proto        void tm_delay(int ticks)
*
*.Params      int ticks - величина задержки в тиках
*                          таймера (за одну секунду таймер
*                          тикает 18.2 раза).
*
*.Return      Ничего
*
*.Sample      tm_samp1.c
**/

#include <dos.h>
#include <conio.h>

void tm_delay(int ticks) {

        _asm {

                push si

                mov  si, ticks
                mov  ah, 0
                int  1ah

                mov  bx, dx
                add  bx, si

delay_loop:

                int  1ah
                cmp  dx, bx
                jne  delay_loop

                pop  si
        }
}



Функция использует только одно слово регистра таймера, что позволяет формировать задержки длительностью до 65536 тиков таймера. Приведенная ниже программа демонстрирует использование функции для генерации примерно десятисекундной задержки :

#include <stdio.h>
#include "sysp.h"


main() {

        printf("\nДля выполнения программной задержки примерно"
                        "\nна 10 секунд нажмите любую клавишу.");
        getch();

        printf("\n\nВремя пошло...");

        tm_delay(18 * 10);

        printf("\nГотово!");

        exit(0);
}



BIOS компьютеров IBM AT содержит еще две интересные функции для работы с таймером. Это функции 83h и 86h прерывания INT 15h.

Функция 83h позволяет запустить таймер на счет, указав адрес некоторого байта в оперативной памяти. Программа, запустившая таймер, сразу после запуска получает управление. По истечении времени, заданного при запуске таймера, функция устанавливает старший бит указанного байта в единицу, сигнализируя таким образом программе о завершении указанного временного интервала. Программа может также отменить работу таймера в этом режиме.

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

Приведем формат вызова функции 83h прерывания INT 15h:

На входе:      AH = 83h;

                AL = код подфункции:

                  0 - установить интервал, запустить таймер;
                  1 - отменить работу таймера;

                CX = старший байт времени работы счетчика,
                  задается в микросекундах;

                DX = младший байт счетчика;

                ES:BX = адрес байта, в котором по истечении
                  интервала времени старший бит будет
                  установлен в 1.

На выходе:      не используются.



Функция 86h специально предназначена для формирования задержек. Она позволяет определять время задержки в микросекундах, что достаточно удобно для многих задач. Во время выполнения задержки разрешены прерывания. Формат вызова функции:

На входе:      AH = 86h;

        CX = старший байт времени задержки,
                задается в микросекундах;

        DX = младший байт времени задержки.

На выходе:      не используются.


В вашем исходнике есть библиотека sisp.h, я ее нимогу найти нигде. Если не сложно отправите на ящик [email protected], или ссылку.
  Вверх
KaraKum
Дата 16.12.2007, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



У меня вопрос: как добывить таймер в форму? В "Toolbox" таймер (как и многие другие элементы) выглядет прозрачным и добавить его нельзя, а добавить его функцией "SetTimer()" не могу, потому что не знаю как Visual C++ назвала указатель на родительское окно. Подскажите!  smile 
PM MAIL WWW   Вверх
MTWizard
Дата 17.12.2007, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 8.10.2007
Где: Київ

Репутация: 3
Всего: 4



Функция QueryPerfomanceCounter - далеко не панацея. Как сказано в MSDN, на многоядерных процессорах она может отдать счётчик любого ядра, а они не обязательно синхронны :(. Так что, имхо, лучше всё-таки использовать мультимедийный. И его можно настроить.

Для того, чтобы увеличить разрешение для мультимедийного таймера, есть функция 
Код

MMRESULT timeBeginPeriod(UINT uPeriod);

Она описана так:"sets the minimum timer resolution for an application or device driver", т.е. как раз то, что надо. Но нужно помнить, что это действие является глобальным, так что после окончания работы с таймерами надо вызвать
Код

MMRESULT timeEndPeriod(UINT uPeriod);

с тем же параметром.
Минимальная точность (точнее, максимальная) равна 1 мс.
По моим замерам, после timeBeginPeriod(1) точность у таймера становится очень неплохой

 smile 
Вроде, это тема для раздела WinAPI
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1675 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.