Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> В обход Sleep (ms) и for (;;), таймер с точным интервалом времени 
V
    Опции темы
zhgutov
Дата 11.4.2006, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Подскажите, можно ли сделать так, чтобы функция вызывалась, скажем, каждые 2 мс, но при этом проц не грузился на «все 100»?
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
_hunter
Дата 11.4.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



ищи по форуму.
заранее могу сказать -- никак не получится


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
zhgutov
Дата 11.4.2006, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я уже поискал. Нашел только то, что не получится. Эээ... Винда, блин.
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Fixin
Дата 11.4.2006, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

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



А чем sleep и for неустраивают?
Код

for (;;)
{
    Func();
    Sleep(2);
}

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


Шустрый
*


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

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



Оно сейчас так и работает. Ситуация похожа на ту, которую ты говорил поискать. У меня в другом потоке графики рисуются. Устройство работает через COM и USB. С USB все в порядке, но COM все вешает. Сигнальные линии в COM не задействованы, событие повесить не могу. Посему хочу найти именно такой способ. К тому же на будущее полезно.
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
_hunter
Дата 11.4.2006, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



Fixin, этот способ не подходит еще по одной причине -- Sleep имеет дискретность в 10 мс


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
VectorMan
Дата 11.4.2006, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Antihero
*


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

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



а WaitForSingleObject не подходит? ещё можно заюзать timeSetEvent
PM   Вверх
zhgutov
Дата 11.4.2006, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



WaitForSingleObject не к чему прикрутить, а про timeSetEvent я не знал, попробую...
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
VectorMan
Дата 11.4.2006, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Antihero
*


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

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



Цитата(zhgutov @ 11.4.2006, 14:33)
WaitForSingleObject не к чему прикрутить,

а так?

Код

event = CreateEvent(NULL, FALSE, FALSE, NULL);

for(;;)
{
  WaitForSingleObject(event, 2);
  MyFunction();
}


хотя наверное у этой функции тоже есть какие то ограничения по точности
PM   Вверх
_hunter
Дата 11.4.2006, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



есть. причем полностью аналогичные ограничениям Sleep' а


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Fixin
Дата 11.4.2006, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

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



Это ограничение существует из-за ограничений самой винды (ее архитектуры), можно только искуственные методы, с которыми я не знаком
PM MAIL ICQ   Вверх
zhgutov
Дата 11.4.2006, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Она почему-то тормозит. Очень сильно тормозит. Может я что делаю не так?
Код

void CALLBACK timer_callback (UINT uTimerID, UINT uMsg, DWORD_PTR timer_ptr, DWORD_PTR dw1, DWORD_PTR dw2)
{
    Timer& timer = *cast <Timer*>(timer_ptr);
    timer.activate ();
}

// ...

bool Timer::get_ready ()
{
    return id = timeSetEvent (delay, accuracy, timer_callback, cast <DWORD_PTR>(this), TIME_PERIODIC);
}

// ...


Это сообщение отредактировал(а) zhgutov - 11.4.2006, 15:40
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Fixin
Дата 11.4.2006, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

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



Создание объекта и преобразование тпов - не быстрая операция
PM MAIL ICQ   Вверх
zhgutov
Дата 11.4.2006, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Объект там не создается и тип не преобразуется (unsigned -> void*). Временной интервал — 50 мс. Пробовал разные значения интервала и точности. Все-равно тормозит. Параллельно работает поток отображения всяких там графиков, проц грузится на 15 %, но тормозит (50 мс -> ~0.5 с)!
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
VectorMan
Дата 11.4.2006, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Antihero
*


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

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



Цитата(zhgutov @ 11.4.2006, 15:38)
Она почему-то тормозит. Очень сильно тормозит.

в MSDN настоятельно рекомендуют перед использованием функций семейства time* устанавливать точность таймера через timeBeginPeriod (и соответственно после окончания работы использовать timeEndPeriod)

Это сообщение отредактировал(а) VectorMan - 11.4.2006, 15:58
PM   Вверх
zhgutov
Дата 11.4.2006, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



И это делаю, результат тот же.
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
zhgutov
Дата 17.4.2006, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Все, нашел! Работает корректно, алгоритм надо было изменить. 
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Олег_Игоревич
Дата 24.4.2006, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Необходимо разработать драйвер.
Муторно но работать будет на 100%. 
--------------------
Используй жизнь ПО ПОЛНОЙ !!!  
PM MAIL   Вверх
takedo
Дата 25.4.2006, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



zhgutov, так непонятно, неужели получилось вызывать таймер с периодом 2 миллисекунды в не RealTime операционке? Если да, то надо это обязательно в фак запихать.  


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
zhgutov
Дата 26.4.2006, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я не измерял. Могу провести исследование на эту тему... Мне необходимо было сделать таймер с периодом 50 мс, а про 2 мс я написал для того, чтобы найти здесь такой способ, не более. Если б написал как есть, подозреваю, что меня бы послали в поиск. Посему так. О результатах скоро напишу. 
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
zhgutov
Дата 26.4.2006, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Вот, можете сами проверить, построить распределение вероятностей... Вроде компилируется.
Код
// main.cpp
#include <cstdio>
#include <timer.hpp>

class X: public Timer
{
    __int64 tick;
    double ms_max;
    int out, count;
public:
    X ();
    void activate ();
    ~X ();
};

void main ()
{
    init_timer ();
    X a;
    a.get_ready ();
    unsigned timer = GetTickCount () + 30 * 1000;
    while (timer > GetTickCount ());
}

X::X (): Timer (2, 0), tick (0), ms_max (-1.0), out (0), count (0)
{
    tick = exec_rdtsc ();
}

X::~X ()
{
    printf ("%G%%\n", out / count * 100.0); // Процент «непопаданий»
}

void X::activate ()
{
    __int64 tick2 = exec_rdtsc ();
    __int64 delta = tick2 - tick;
    tick = tick2;
    double ms = double (delta) / timer_scale;
    if (ms > delay)
    {
        printf ("%G\n", ms);
        ms_max = ms;
        ++out;
    }
    ++count;
}

«Нашлепка» для таймера:
Код
// timer.hpp
#pragma once

#include <tchar.h>
#include <windows.h>
#include <mmsystem.h>

void init_timer ();
__int64 exec_rdtsc ();

extern __int64 timer_scale;

class Timer
{
    friend void CALLBACK timer_callback (UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR);
public:
    Timer (unsigned delay, unsigned accuracy): handle (NULL), delay (delay), accuracy (accuracy) { }

    virtual bool get_ready ();
    virtual void complete ();

    virtual ~Timer () { complete (); }

protected:
    Timer (const Timer&);
    Timer& operator = (const Timer&);

    virtual void activate () = 0;

    MMRESULT handle;
    unsigned delay, accuracy;
};

Реализация «нашлепки» для таймера:
Код
// timer.cpp
#include <timer.hpp>

const int TIMER_TEST_TIME = 1000; // msec
__int64 timer_scale;

__int64 exec_rdtsc ()
{
    static __int64 result;
    _asm
    {
        rdtsc    // ReaD from Time Stamp Counter
        mov    ebx, offset result
        mov    dword ptr [ebx], eax
        mov    dword ptr [ebx + 4], edx
    }
    return result;
}

void init_timer ()
{
    __int64 start_timer, stop_timer;
    HANDLE current_process = GetCurrentProcess ();
    DWORD common_priority = GetPriorityClass (current_process);
    SetPriorityClass (current_process, REALTIME_PRIORITY_CLASS);
    DWORD tick_count = GetTickCount (), timer = tick_count + TIMER_TEST_TIME;
    start_timer = exec_rdtsc ();
    while (timer > GetTickCount ());
    stop_timer = exec_rdtsc ();
    SetPriorityClass (current_process, common_priority);
    timer_scale = (stop_timer - start_timer) / TIMER_TEST_TIME;
}

void CALLBACK timer_callback (UINT uTimerID, UINT uMsg, DWORD_PTR thread_ptr, DWORD_PTR dw1, DWORD_PTR dw2)
{
    Timer& timer = *cast <Timer*>(thread_ptr);
    timer.activate ();
}

bool Timer::get_ready ()
{
    timeBeginPeriod (accuracy);
    handle = timeSetEvent (delay, accuracy, timer_callback, cast <DWORD_PTR>(this), TIME_PERIODIC);
    return handle != NULL;
}
void Timer::complete ()
{
    if (handle != NULL)
    {
        timeKillEvent (handle);
        handle = NULL;
        timeEndPeriod (accuracy);
    }
}

timer > x из командной строки пишет у меня в x следующее:
Цитата
15.8527
2.96936
2.97209
2.96961
2.96853
2.97072
2.96829
2.96918
2.96884
2.96854
2.96822
2.96965
2.9632
2.96945
2.9695
2.9695
2.96833
2.96683
2.96956

...

2.96898
2.97007
2.96409
2.9694
2.96743
2.27022
2.68064
2.01943
2.96736
2.96892
0%

А потом, при желании, это можно запихать в фак.   

Это сообщение отредактировал(а) zhgutov - 26.4.2006, 14:55
--------------------
Приполз. Увидел. Укусил.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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