Войти
ПрограммированиеФорумОбщее

Обёртка над QPC (комментарии) (2 стр)

Страницы: 1 2 3 Следующая »
#15
11:34, 18 мар. 2011

KpeHDeJIb
> Нет гарантий.
У QPC нет гарантий только если баги на уровне хала или биоса. Внезапно, если у тебя кривое железо - нормально работать не будет. На кривом железе вообще нет гарантий что что-то будет нормально работать.


#16
14:16, 18 мар. 2011

@!!ex
> Внезапно, если у тебя кривое железо - нормально работать не будет.
Внезапно. Половина железа на рынке кривое. Внезапно!

#17
19:31, 18 мар. 2011

KpeHDeJIb
Не покупай железо на черном рынке в китае.

#18
19:31, 18 мар. 2011

Сейчас найти железо, которое бы криво работало с QPC - мало реально. Были у АМд проблемы, сам с ними сталкивался, уже давно нету, кстати.

#19
19:40, 18 мар. 2011

меня когда торкнуло я  вот такую фигню написал.

namespace core
{
  namespace time
  {
    struct STimerInfo
    {
        friend class CTimerMult;
      public:
        inline void clearCount();
        inline uint64 getCountTicks();
        inline uint64 getFrameTicks();
        inline uint64 getTicksPerSecond();
        inline double getFrameTicksD();
        inline double getFrameSecondD();
        inline double getCountSecondD();
        inline uint64 getResidueTicks();
        inline uint64 getResiduePerTicks();
        inline double getResidueTicksD();
      private:
        inline STimerInfo();
        inline ~STimerInfo();
        uint64 _countTicks;
        uint64 _frameTicks;
        uint64 _ticksPerSecond;
        double _countSecondD;
        double _frameTicksD;
        double _frameSecondD;
        uint64 _residueTicks;
        uint64 _residuePerTicks;
        double _residueTicksD;
    };


    struct STimerSysInfo
    {
        friend class CTimerSys;
        friend class CTimerMult;
      public:
        inline uint64 getFrameTicks();
        inline uint64 getTicksPerSecond();
        inline double getFrameSecondD();
      private:
        inline STimerSysInfo();
        inline ~STimerSysInfo();
      private:
        uint64 _frameTicks;
        uint64 _ticksPerSecond;    
        double _frameSecondD;
    };

    class CTimerSys
    {
      public:
        CTimerSys();
        ~CTimerSys();
        void scan();
        STimerSysInfo info;
      private:
        LARGE_INTEGER _timeStart,_timeFrequency;
    };

    class CTimerMult
    {
      public:
        CTimerMult(const uint64& ticksPerSecond);
        ~CTimerMult();
        void elapsedTime(STimerSysInfo& timerInfo);
        STimerInfo info;
    };

  }//time
}//core
полная версия core

#20
19:55, 18 мар. 2011

Господа, обёртка над QPC есть в MSDN:
http://msdn.microsoft.com/en-us/library/ms644904(v=vs.85).aspx
Немного допиливания напильником и ок.

#21
1:04, 19 мар. 2011

Нашел в одном OpenSource проекте вот этот код

uint32_t GetTicks( )
{
#ifdef WIN32
  // don't use GetTickCount anymore because it's not accurate enough (~16ms resolution)
  // don't use QueryPerformanceCounter anymore because it isn't guaranteed to be strictly increasing on some systems and thus requires "smoothing" code
  // use timeGetTime instead, which typically has a high resolution (5ms or more) but we request a lower resolution on startup
    return timeGetTime( );
#elif __APPLE__
  uint64_t current = mach_absolute_time( );
  static mach_timebase_info_data_t info = { 0, 0 };
  // get timebase info
  if( info.denom == 0 )
    mach_timebase_info( &info );
  uint64_t elapsednano = current * ( info.numer / info.denom );
  // convert ns to ms
  return elapsednano / 1e6;
#else
  uint32_t ticks;
  struct timespec t;
  clock_gettime( CLOCK_MONOTONIC, &t );
  ticks = t.tv_sec * 1000;
  ticks += t.tv_nsec / 1000000;
  return ticks;
#endif
}

Смутила строчка don't use QueryPerformanceCounter anymore because it isn't guaranteed to be strictly increasing on some systems and thus requires "smoothing" code.
Кто что думает по этому поводу?

#22
4:20, 19 мар. 2011

dev
> Смутила строчка don't use QueryPerformanceCounter
> Кто что думает по этому поводу?
Никто ничего не думает. Просто не используют. Если пишешь что-то для себя - ради бога. Если что-то глобальное - зачем тебе лишние проблемы? timeBeginPeriod(1) для игр хватает за глаза. Тем более с нынешним засильем низкого фпс.

#23
9:12, 19 мар. 2011

entryway
> Просто не используют.
Мы используем. имели проблемы только на АМД, но это было давно.

entryway
> timeBeginPeriod(1) для игр хватает за глаза.
У него все равно точность 16 мс. Это мало.

#24
16:40, 3 июня 2011

@!!ex
> У него все равно точность 16 мс. Это мало.

возможно timeBeginPeriod(1) работает иначе
вот в этой статье есть:

http://www.dtf.ru/articles/read.php?id=39888&page=2

#25
19:29, 7 июля 2011

В обертке не учитывается точность таймера.
Моя обертка:

class CTIMER
{
  public:
    PBL_INLINE CTIMER();
    PBL_INLINE VOID Reset();
    // Функция возвращает время с момента запуска таймера (в мс)
    PBL_INLINE F64 GetRealTime() const;
    PBL_INLINE F64 GetDeltaTime();
  private:
    PBL_ALIGN(16) F64  m_Resolution;
    PBL_ALIGN(16) S64  m_nStartTime;
    PBL_ALIGN(16) F64  m_LastTime;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
CTIMER::CTIMER() : m_LastTime(0)
{
  PBL_ALIGN(16) S64 nFreq;
  ::QueryPerformanceFrequency((PLARGE_INTEGER)&nFreq);
  m_Resolution = 1000.0 / (F64)nFreq;
  ::QueryPerformanceCounter((PLARGE_INTEGER)&m_nStartTime);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
VOID CTIMER::Reset()
{
  m_LastTime = GetRealTime();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
F64 CTIMER::GetRealTime() const
{
  PBL_ALIGN(16) S64 nCurTime;
  ::QueryPerformanceCounter((PLARGE_INTEGER)&nCurTime);
  return m_Resolution*(F64)(nCurTime-m_nStartTime);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
F64 CTIMER::GetDeltaTime()
{
  PBL_ALIGN(16) F64 CurTime(GetRealTime());
  PBL_ALIGN(16) F64 m_DeltaTime(CurTime-m_LastTime);
  m_LastTime = CurTime;
  return m_DeltaTime;
}

#26
10:49, 28 сен. 2011

Ну и ужасы здесь написаны. На самом деле все намного проще (делюсь своим классом типа :))

  class IntervalTimer
  {
  public:
    IntervalTimer(bool runNow) : _startTime(0.0f), _endTime(0.0f) 
      { if (runNow) run(); }

    void run() 
    { 
      _runTime = queryTime();
      _startTime = _runTime; 
    }

    float lap()
    {
      _endTime = queryTime();
      float dt = _endTime - _startTime;
      _startTime = _endTime;
      return dt;
    }

    float duration()
      { return queryTime() - _runTime; }

  private:
    float _runTime;
    float _startTime;
    float _endTime;
  };

Использование:

  IntervalTimer timer(true);
...
  std::cout << " done (" << timer.lap() << " msec) " << std::endl << "Computing tangents ... ";
...
  std::cout << " done (" << timer.lap() << " msec) " << std::endl << "Gathering data...";
...
  std::cout << " done (" << timer.lap() << " msec) " << std::endl;

Правка: queryTime - платформеннозависимое получение текущего времени

#27
14:33, 28 сен. 2011

Sergio
> Правка: queryTime - платформеннозависимое получение текущего времени
А поподробнее про эту функцию.

#28
17:32, 28 сен. 2011

Под виндой:

float queryTime()
{
  __int64 COUNTER;
  __int64 FREQ;
  QueryPerformanceCounter((LARGE_INTEGER*)&COUNTER);
  QueryPerformanceFrequency((LARGE_INTEGER*)&FREQ);
  return static_cast<float>(static_cast<double>(COUNTER) / static_cast<double>(FREQ));
} 

Под айфоном:

double __queryTime()
{
  timeval tv;
  gettimeofday(&tv, 0);
  return static_cast<double>(tv.tv_sec) + static_cast<double>(tv.tv_usec) / 1000000.0;
}

float et::queryTime()
{
  if (!startTimeInitialized)
  {
    startTime = __queryTime();
    startTimeInitialized = true;
  };
  return static_cast<float>(__queryTime() - startTime);
} 

#29
17:55, 28 сен. 2011

Sergio
> Sergio
ну это неинтересно все только интервал.

core::time::CTimerSys timeSys; //сам таймер
core::time::CTimerMult timerAnimFire(32,60); // таймер 32 тика в 60сек. 
core::time::CTimerMult timerAnim(24,60); // таймер 24 тика в 60сек. 

timeSys.scan();
timerAnimFire.elapsedTime( timeSys.info );
timerAnim.elapsedTime( timeSys.info );

....
timeSys.scan();
timerAnimFire.elapsedTime( timeSys.info );
timerAnim.elapsedTime( timeSys.info );

printf("%i",timeSys.info.getFrameSecondD() ) ;//  сколько секунд в фрейме
printf("%f",timeSys.info.getFrameTicks() ) ;//  сколько тиков в фрейме
printf("%i",timeSys.info.getTicksPerSecond() ) ;//  сколько тиков в в секунде.  константа (1<<32);

timerAnimFire.frame.gatTicksD();// сколько ТИКОВ во фрейме.
timerAnimFire.ticks.gatTicks();//сколько во фрейме было тиков с учетом НАКОПЛЕНИЯ ОСТАТКА.
timerAnimFire.ticks.gatTicksD();//сколько во фрейме было тиков с учетом накопления остатка. дробная.
timerAnimFire.ticks.gatResidueD();// gatTicksD() - gatTicks().

например если у нас анимация каждые 30кадров в сек.
то timerAnimFire.ticks.gatTicks() на тот фрейм в котором произошел переход между секундами то даст 1, если было 2 перехода  то даст 2 ..
timerAnimFire.ticks.gatResidueD()  легко использовать для интерполяции между тиками чего либо.

особенность что это считается на целочисленной логики и таймера CTimerMult (1,60) / CTimerMult(10,60), CTimerMult(3,60)...  сработают одновременно все на 60сек.
удобно в одном месте менять скорость таймеров.

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.