crossplatform.ru

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


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

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

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


Последние 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 Текстовая версия Сейчас: 28.3.2024, 14:43