crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в требуется кросплатформенный счётчик "тиков"
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Iron Bug Дата 24.3.2011, 8:07
  Сегодня заговорили про таймеры на лине, и я вспомнила про один глючок таймеров на венде. Глючок противный, может, кому понадобится инфа про него. Конечно, на новых чипсетах этот глюк наверняка не присутствует, но знать полезно, а то напорешься - хрен догадаешься, что и почему.
Суть в том, что на некоторых материнках из-за проблем с южным мостом при нагрузке на PCI имеют место внезапные скачки счётчика QueryPerformanceCounter вперёд аж на несколько секунд. Так что нужно делать доп. проверку, сравнивая ещё и секундные показания с других таймеров.
Вот инфа от мелкософта, там и пример кода, как дополнительную проверку делать, и список глюкавых мостов:
http://support.microsoft.com/kb/274323

Litkevich Yuriy Дата 25.9.2010, 17:27
 
Цитата(DEADHUNT @ 25.9.2010, 19:14) *
не пробовал?
неа, меня полностью устроило решение предложенное BRE
DEADHUNT Дата 25.9.2010, 15:14
 
#include <ctime>
clock_t clock();

не пробовал?
Litkevich Yuriy Дата 24.9.2010, 20:33
  собственно, в результате использовал это:
Цитата(BRE @ 20.12.2009, 23:34) *
Посмотри на файл src/testlib/3rdparty/cycle_p.h
Iron Bug Дата 22.12.2009, 10:03
  убираю копию... чота сеть глюканула - два раза послалось. сорри.
Iron Bug Дата 22.12.2009, 10:03
  полгода назад тот же вопрос меня мучил. нарыла в какой-то статье реализацию счётчика, маленько переделала под свои нужны. примерно вот так вышло (выкусываю куски кода, ибо весь он сильно объёмный и там не просто счётчики, а отдельный поток с организацией дилеев реализован для моих хардварных нужд):

 // это инициализация
  #ifndef __linux__
       ::QueryPerformanceFrequency(&frequency);
       simplistic_synchronize(ref_point);
  #endif

 // это использование
        #ifdef __linux__
        // pt - типа boost::posix_time::ptime
        pt = microsec_clock::universal_time();  // это из boost - там под линём всё OK с таймерами
        #else
        pt = get_total_microseconds(); // под вендой начинаем извращаться через QueryPerformanceCounter
        #endif


детали реализации счётчика под венду:

это файл для счётчика под венду (идея в замерах по счётчику и периодической синхронизации его с системным временем для устранения набежавшей погрешности). взято хоть убей не помню откуда, возможно, что-то я ещё переделывала потом - уже плохо помню чего там было, но код работает:
typedef ptime time_type; // это boost::posix_time::ptime
struct reference_point
{
  FILETIME file_time;
  LARGE_INTEGER counter;
};

reference_point ref_point;
LARGE_INTEGER   frequency;
mutex           mtx;

void simplistic_synchronize(reference_point& ref_point)
{
  FILETIME      ft0 = { 0, 0 },
                ft1 = { 0, 0 };
  LARGE_INTEGER li;

  //
  // Spin waiting for a change in system time. Get the matching
  // performance counter value for that time.
  //
  ::GetSystemTimeAsFileTime(&ft0);
  do
  {
    ::GetSystemTimeAsFileTime(&ft1);
    ::QueryPerformanceCounter(&li);
  }
  while ((ft0.dwHighDateTime == ft1.dwHighDateTime) &&
         (ft0.dwLowDateTime == ft1.dwLowDateTime));

  ref_point.file_time = ft1;
  ref_point.counter = li;
}

void get_time(LARGE_INTEGER frequency, const reference_point&
    reference, FILETIME& current_time)
{
  LARGE_INTEGER li;

  ::QueryPerformanceCounter(&li);

  //
  // Calculate performance counter ticks elapsed
  //
  LARGE_INTEGER ticks_elapsed;

  ticks_elapsed.QuadPart = li.QuadPart -
      reference.counter.QuadPart;

  //
  // Translate to 100-nanoseconds intervals (FILETIME
  // resolution) and add to
  // reference FILETIME to get current FILETIME.
  //
  ULARGE_INTEGER filetime_ticks,
                 filetime_ref_as_ul;

  filetime_ticks.QuadPart =
      (ULONGLONG)((((double)ticks_elapsed.QuadPart/(double)
      frequency.QuadPart)*10000000.0)+0.5);
  filetime_ref_as_ul.HighPart = reference.file_time.dwHighDateTime;
  filetime_ref_as_ul.LowPart = reference.file_time.dwLowDateTime;
  filetime_ref_as_ul.QuadPart += filetime_ticks.QuadPart;

  //
  // Copy to result
  //
  current_time.dwHighDateTime = filetime_ref_as_ul.HighPart;
  current_time.dwLowDateTime = filetime_ref_as_ul.LowPart;
}

time_type create_time(FILETIME& ft) {
      // offset is difference (in 100-nanoseconds) from
      // 1970-Jan-01 to 1601-Jan-01
      boost::uint64_t c1 = 27111902;
      boost::uint64_t c2 = 3577643008UL; // 'UL' removes compiler warnings
      const boost::uint64_t OFFSET = (c1 << 32) + c2;

      boost::uint64_t filetime = ft.dwHighDateTime;
      filetime = filetime << 32;
      filetime += ft.dwLowDateTime;
      filetime -= OFFSET;
      // filetime now holds 100-nanoseconds since 1970-Jan-01

      // microseconds -- static casts supress warnings
      boost::uint32_t sub_sec = static_cast<boost::uint32_t>((filetime % 10000000) / 10);

      std::time_t t = static_cast<time_t>(filetime / 10000000); // seconds since epoch

      std::tm *curr_ptr = 0;
      curr_ptr = std::gmtime(&t);//, &curr);

      ptime::date_type d(curr_ptr->tm_year + 1900,
                  curr_ptr->tm_mon + 1,
                  curr_ptr->tm_mday);

      //The following line will adjusts the fractional second tick in terms
      //of the current time system.  For example, if the time system
      //doesn't support fractional seconds then res_adjust returns 0
      //and all the fractional seconds return 0.
      int adjust = static_cast<int>(ptime::time_duration_type::rep_type::res_adjust()/1000000);

      ptime::time_duration_type td(curr_ptr->tm_hour,
                            curr_ptr->tm_min,
                            curr_ptr->tm_sec,
                            sub_sec * adjust);
      return time_type(d,td);

    }


time_type get_total_microseconds(void)
{
     FILETIME  ft;
     {
        mutex::scoped_lock l(mtx);
        get_time(frequency, ref_point, ft);
     }
     return create_time(ft);
}


P.S. я тут быстро из кода навыдирала кусочков и комменты маленько добавила, могла чего-нить забыть. но в общем, я думаю, идея понятна.
Litkevich Yuriy Дата 21.12.2009, 2:42
 
Цитата(trdm @ 21.12.2009, 5:29) *
GetTickCount
ы?
Цитата
The return value is the number of milliseconds that have elapsed since the system was started.


Там же нашёл, что-то похожее на то, что мне нужно: QueryPerformanceCounter

И ещё QueryUnbiasedInterruptTime про который написано:
Цитата
Points to a variable to receive the unbiased interrupt-time count in system time units of 100 nanoseconds.


Цитата(BRE @ 20.12.2009, 23:34) *
Посмотри на файл src/testlib/3rdparty/cycle_p.h
а вот это походу в яблочко. Буду штудировать
trdm Дата 21.12.2009, 2:29
 
Цитата(Litkevich Yuriy @ 20.12.2009, 23:50) *
Цитата(ViGOur @ 21.12.2009, 2:03) *
потому тики будут точными на каждые 100 мс
для системного (низкоуровнего) счётчика, тики будут соответствовать точности кварцевого резонатора (с соответствующим коэфф. деления).

Меня не интересует ширпотребный таймер/часы. именно счётчик тиков

GetTickCount
ы?
+
#include <sys/time.h>
unsigned long GetTickCount()
{
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return (tv.tv_sec*1000+tv.tv_usec/1000);
}
Litkevich Yuriy Дата 20.12.2009, 23:50
 
Цитата(ViGOur @ 21.12.2009, 2:03) *
потому тики будут точными на каждые 100 мс
для системного (низкоуровнего) счётчика, тики будут соответствовать точности кварцевого резонатора (с соответствующим коэфф. деления).

Меня не интересует ширпотребный таймер/часы. именно счётчик тиков
ViGOur Дата 20.12.2009, 23:03
  Но так же нужно не забывать, что мы работаем не в ОС реального времени, потому тики будут точными на каждые 100 мс, на меньший промежуток времени нет. Ребята помнится уже как-то (достаточно давно) проверяли это дело на другом форуме.

И 100 мс справедливо помнится для винды, для никсов не помню проверяли или нет.
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 0:24