crossplatform.ru

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

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> требуется кросплатформенный счётчик "тиков"
Litkevich Yuriy
  опции профиля:
сообщение 20.12.2009, 17:19
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


нужно средство для измерения относительного времени, быстрое.

У меня мысли только о неком счётчике "тиков", который, я думаю, есть в каждой ОСьке.
Возможно в стандарте Си/Си++ есть что-то такое, но я со стандартными вещами в этих языках плохо знаком.

Подкиньте идеи пожалуйста.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 20.12.2009, 17:43
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 601
Регистрация: 2.2.2009
Пользователь №: 523

Спасибо сказали: 101 раз(а)




Репутация:   9  


Не совсем понял проблемы. Чем обычный QTimer не подходит?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 20.12.2009, 18:16
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Kagami @ 20.12.2009, 20:43) *
Чем обычный QTimer не подходит?
это довольно жирный класс, как следствие не быстрый.
Но самое главное это разрешающая способность - 1 мс. => 1 МГц, частота проца (ядра) сотни/тысячи мегагерц (единицы/десятки наносекунд)

Должен быть счётчик тикающий со скоростью 1/10 или 1/100 тактовой частоты ядра. Применять, например, в таком стиле:
...
int tic1, tic2, tic3;
tic1 = getTic();
// фрагмент кода
tic2 = getTic();
// фрагмент кода
tic3 = getTic();
// что-то сделать со снимками тиков
Нужно для тестовых измерений производительности.

Задача не позволяет делать измерительные циклы
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 20.12.2009, 20:34
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Посмотри на исходники QTestLib, там вроде есть режим подсчета тиков процессора.

Цитата
The code insde the QBENCHMARK macro will be measured, and possibly also repeated several times in order to get an accurate measurement. This depends on the selected measurement back-end. Several back-ends are available an can be selected on the command line:
Имя Commmand-line Arguemnt Availability
Walltime (default) All platforms
CPU tick counter -tickcounter Windows, Mac OS X, Linux, many UNIX-like systems.
Valgrind/Callgrind -callgrind Linux (if installed)
Event Counter -eventcounter All platforms

Вот отсюда: http://doc.crossplatform.ru/qt/4.5.0/qtestlib-manual.html

Посмотри на файл src/testlib/3rdparty/cycle_p.h


Сообщение отредактировал BRE - 20.12.2009, 21:20
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 20.12.2009, 23:03
Сообщение #5


Мастер
******

Группа: Модератор
Сообщений: 3291
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


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

И 100 мс справедливо помнится для винды, для никсов не помню проверяли или нет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 20.12.2009, 23:50
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(ViGOur @ 21.12.2009, 2:03) *
потому тики будут точными на каждые 100 мс
для системного (низкоуровнего) счётчика, тики будут соответствовать точности кварцевого резонатора (с соответствующим коэфф. деления).

Меня не интересует ширпотребный таймер/часы. именно счётчик тиков
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
trdm
  опции профиля:
сообщение 21.12.2009, 2:29
Сообщение #7


Дмитрий Трошин
****

Группа: Участник
Сообщений: 575
Регистрация: 12.1.2008
Пользователь №: 68

Спасибо сказали: 21 раз(а)




Репутация:   6  


Цитата(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);
}


Сообщение отредактировал trdm - 21.12.2009, 2:32
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 21.12.2009, 2:42
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(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
а вот это походу в яблочко. Буду штудировать
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.12.2009, 10:03
Сообщение #9


Профессионал
*****

Группа: Модератор
Сообщений: 1594
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


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

 // это инициализация
  #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. я тут быстро из кода навыдирала кусочков и комменты маленько добавила, могла чего-нить забыть. но в общем, я думаю, идея понятна.

Сообщение отредактировал Iron Bug - 22.12.2009, 10:12
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.12.2009, 10:03
Сообщение #10


Профессионал
*****

Группа: Модератор
Сообщений: 1594
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


убираю копию... чота сеть глюканула - два раза послалось. сорри.

Сообщение отредактировал Iron Bug - 22.12.2009, 10:06
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 24.2.2020, 21:16