OSDev
http://osdev.su/

Системное время
http://osdev.su/viewtopic.php?f=6&t=93
Страница 1 из 1

Автор:  pushkoff [ 19 июл 2007, 11:09 ]
Заголовок сообщения:  Системное время

Раз никто не хочет создавать новую тему, то я создам...
В теме План разработки операционной системы FOS (TODO) мы начали обсуждение таймеров и расчета времени, давайте тут продолжим...

В моей системе время расчитывается при помощи команды RDTSC и частоты процессора. Кому интересно могу выложить формулы и исходные коды этого метода, но не скоро, так как нет исходника под рукой... (кому невтерпеж, могут попросить исходники моей оси у DinamytE)

Автор:  pavia [ 19 июл 2007, 15:38 ]
Заголовок сообщения:  Re: Системное время

Pushkoff,
А как ты определяешь, частоту процессора?

Автор:  dinamyte [ 19 июл 2007, 16:08 ]
Заголовок сообщения:  Re: Системное время

Цитата:
Кому невтерпеж, могут попросить исходники моей оси у DinamytE

http://osdev.ru/store/myos.zip

Автор:  pushkoff [ 19 июл 2007, 18:53 ]
Заголовок сообщения:  Re: Системное время

Код:
#include <cpu.h>#include <systime.h>#include <sysdata.h>#include <lock.h>

/************************************************
 tacts=(1<<32)*time

  tact - tsc
  time - length of tacts

     1 tact = (1<<32) * time_per_tact

      time_per_tact = 1 sec / frequency

 1 tact = (1<<32) * 1 sec / frequency

      1 sec =1 000 000 usec

     1 sec / frequency = 1 000 000 usec / frequency = 50 000 usec / (frequency/20) 

   1 tact = (1<<32)*50 000 usec /(frequency/20)

      time[i+1] = (tacts[i]*(1 tact)+utacts[i])/(1<<32)
  utacts[i+1] = (tacts[i]*(1 tact)+utacts[i])%(1<<32)
       
************************************************/

static unsigned __int64 tsc_delta()
{
      __int64 tsc=sys_tsc;
       sys_tsc=cpu_read_tsc();
        return sys_tsc-tsc;
}

static SYSTEM_TIME tsc_to_time(unsigned __int64 tsc)
{
      SYSTEM_TIME time=0UL;
      unsigned factor=sys_factor;
        static unsigned __int64 utsc=0UL;
  tsc=tsc*factor+utsc;
       time=tsc/0x100000000UL;
        utsc=tsc%0x100000000UL;
        return time;
}
#define time_lock() lock_lock(&sys_timelock)#define time_unlock() lock_unlock(&sys_timelock);

// run only in interrupt disabled mode
SYSTEM_TIME time_update()
{
   time_lock();
   sys_time+=tsc_to_time(tsc_delta());
    time_unlock();
 return sys_time;       
}

SYSTEM_TIME time_get_time(unsigned *low, unsigned *hi)
{
       SYSTEM_TIME time;
  time_lock();
   time=sys_time+sys_start_time;
  time_unlock();
 if (low&&hi)
   {
  *low=((unsigned*)&time)[0];
  *hi=((unsigned*)&time)[1];
       }
  return time;
}

SYSTEM_TIME time_get_uptime(unsigned *low, unsigned *hi)
{
 SYSTEM_TIME time;
  time_lock();
   time=sys_time;
 time_unlock();
 if (low&&hi)
   {
  *low=((unsigned*)&time)[0];
  *hi=((unsigned*)&time)[1];
       }
  return time;
}


Автор:  pushkoff [ 19 июл 2007, 19:17 ]
Заголовок сообщения:  Re: Системное время

ну и поясню
метод основывается на расчете количества секунд (изначально) в одном такте
так как это число будет дробным то домножим его на 2^32
отсюда получаем 1 (более общий случай) и 2 (для одного такта) формулу
Код:
  tacts=(1<<32)*time (1)

      tact - tsc
      time - length of tacts

1 tact = (1<<32) * time_per_tact (2)


с другой стороны, время одного такта вычисляется так (3)
Код:
time_per_tact = 1 sec / frequency (3)


обьединив (2) и (3) получим (4)

Код:
1 tact = (1<<32) * 1 sec / frequency (4)


то есть результатом (4) будет константа для перехода от количества тактов к времени, которая расчитывается заранее исходя из частоты процессора. дальнейшие формулы привязываются только к расчету частоты (я считал количество тактов за 50 мс и умножал его на 20 для получения частоты)
в программе эта константа называется factor.

время у меня расчитывается в микросекундах (отсюда значение 50000, тк 50 мс = 50000 мкс)

при умножении количества тактов (32 разрядная величина) на фактор времени мы получим 64 разрядное число в старших 32 разрядах которого будет храниться количество микросекунд.
Для увеличения точности, остаток (то есть младшие 32 разряда) сохраняются и при последующих вычислениях используется для корекции

таким методом можно расчитывать временные интервалы длинной до 1 с, так как на 4 ГГц проце разница показаний счетчика тактов, при разнице более чем в 1 секунду, не влезть в 32 разрядное число. (хотя при такой частоте фактор будет очень маленькой величиной, то есть если взять разницу показаний счетчика тактов как 64 разрядную величину, то умножение на фактор не даст переполнения)

Автор:  pushkoff [ 21 июл 2007, 10:39 ]
Заголовок сообщения:  Re: Системное время

Я вот незнаю, как будет работать метод при изменяемой частоте процессора (на ноутбуках есть эта фишка), или на счетчик тактов это не влияет???

Автор:  pushkoff [ 28 июл 2007, 15:33 ]
Заголовок сообщения:  Re: Системное время

Ну если у кого есть какая инфа - делитесь, буду совершенствовать...

Автор:  pavia [ 28 июл 2007, 19:35 ]
Заголовок сообщения:  Re: Системное время

Мой совет. Брать самый быстрый и точный таймер который есть в системе.

PROGRAMMABLE INTERVAL TIMER (PIT 8254) По дэфолту 65536/1193180 максимальная частота 1.193180Гц
В современных системах тактируется от таймера 14.31818 МГц/12

Power Management 1 Timer (PM Timer ) 3.579545 МГц (14.31818 МГц / 4)

High-Precision Event Timer (HPET) 14.31818 МГц

Частота процессора.

Автор:  pushkoff [ 30 июл 2007, 10:38 ]
Заголовок сообщения:  Re: Системное время

вот статейку нашел
http://netch.livejournal.com/39976.html

Автор:  pushkoff [ 10 авг 2007, 16:01 ]
Заголовок сообщения:  Re: Системное время

Вот нашел в исходниках линукса определение частоты при SpeedStep'e
http://www.linux-m32r.org/lxr/http/sour ... step-lib.c

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/