Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Сколько работало времени


Автор: DelphiMaster 18.2.2006, 15:30
Ещё вопрос, а как не задать память приложению, а узнать, сколько точно времени оно работало и сколько динамической памяти заняло. И если можно пример??? smile smile smile

Автор: Демо 18.2.2006, 20:58
Цитата(DelphiMaster @ 18.2.2006, 15:30 Найти цитируемый пост)
сколько точно времени оно работало


GetProcessTimes,GetThreadTimes

Автор: SoWa 18.2.2006, 21:18
А GetTickCount не будет работать, если взять его в начале программы и в конце. А потом вычесть?

Автор: Демо 18.2.2006, 22:33
Цитата(SoWa @ 18.2.2006, 21:18 Найти цитируемый пост)
А GetTickCount не будет работать, если взять его в начале программы и в конце. А потом вычесть?


Не хочется думать, что автор не понимает, как вычисляются промежутки между двумя точками времени.
Скорее уж его интересует время, которое программа реально работала, а не простаивала.
Добавлено @ 22:35
Добавлю, что GetTickCount не поможет. Скорее уж просто Now в начале и в нужный момент времени.

У меня есть программы, которые работают месяцами. Тут GetTickCount бессилен.

Автор: DelphiMaster 19.2.2006, 04:07
У меня программа консольная. И вы правы GetTickCount бессилен он выдаёт не точное время, а приблизительное. Дайте, пожалуйста, пример как использовать функцию GetProcessTimes. smile

Автор: Albinos_x 19.2.2006, 11:58
Цитата(DelphiMaster @ 19.2.2006, 04:07 Найти цитируемый пост)
И вы правы GetTickCount бессилен он выдаёт не точное время, а приблизительное

это как - приблизительное?

а почему не хочешь сделать как сказал Демо?
Код
...
var D:TDateTime;
    yy,mm,dd,hh,min,sec,msec:Word;
    S:String;
...
begin
d:=now;
...
d:=now-d;
DecodeDateTime(d,yy,mm,dd,hh,min,sec,msec);
s:='Функция работала '+inttostr(yy)+' лет '+inttostr(mm)+' месяцев '+inttostr(dd)+' дней '+inttostr(hh)+' часов '+inttostr(min)+' минут '+inttostr(sec)+' секунд '+inttostr(msec)+' милисекунд ';
...

Автор: Демо 19.2.2006, 12:36
Цитата(DelphiMaster @ 19.2.2006, 04:07 Найти цитируемый пост)
У меня программа консольная. И вы правы GetTickCount бессилен он выдаёт не точное время, а приблизительное


Это вряд ли. GetTickCount выдает количество миллисикунд, прошедшее со времени последней загрузки системы. Поэтому приблизительное время GEtTickCount выдавать не может. Другое дело, если у тебя программа работает больше 49,7 дней непрерывно. В этом случае отсчет начинается с нуля.

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

Автор: DelphiMaster 20.2.2006, 08:15
Спасибо!!! smile
Сколько динамической памяти заняло!!! Как унать!!! smile smile smile

Автор: _hunter 20.2.2006, 11:46
GlobalMemoryStatus

Автор: malor 28.7.2011, 16:22
Код
D: = Now;
Функция в этом месте пишет строку из десятка цифр в текстовой файл
D := Now - d;
DecodeDateTime(D, yy, mm, dd, hh, min, sec, msec);
strLog := 'Разница времени: ' + IntToStr(min) + ' минут ' + IntToStr(sec) + ' секунд ' + IntToStr(msec) + ' милисекунд ';


Так вот текст strLog:
Разница времени: 0 минут 0 секунд 0 милисекунд 

Запись в файл длится менее одной миллисекунды?

Delphi XE
Цитата
CPU Type   DualCore Intel Pentium E2180, 2000 MHz (10 x 200)  
Motherboard Name   Gigabyte GA-P31-ES3G (3 PCI, 3 PCI-E x1, 1 PCI-E x16, 2 DDR2 DIMM, Audio, Gigabit LAN)  
Motherboard Chipset   Intel Bearlake P31  
System Memory   3328 MB (DDR2-800 DDR2 SDRAM)  
DIMM1: Hynix HYMP125U64CP8-S5   
2 GB DDR2-800 DDR2 SDRAM (5-5-5-18 @ 400 MHz) (4-4-4-12 @ 266 MHz) (3-3-3-9 @ 200 MHz)  
DIMM3: Samsung M3 78T5663RZ3-CF7
2 GB DDR2-800 DDR2 SDRAM (6-6-6-18 @ 400 MHz) (5-5-5-15 @ 333 MHz) (4-4-4-12 @ 266 MHz)    

Автор: bems 17.10.2011, 22:45
1. Действительно может быть меньше, потому что совсем не обязательно происходит реальная запись. Это же буфферизуется
2. Не используй Now. Еспользуй GetProcessTimes/GetThreadTimes

Автор: northener 17.10.2011, 23:28
Цитата(bems @  17.10.2011,  22:45 Найти цитируемый пост)
2. Не используй Now. Еспользуй GetProcessTimes/GetThreadTimes 

Для определения не очень больших интервалов времени всегда предпочитал использовать QueryPerformanceCounter. С GetProcessTimes/GetThreadTimes не работал. Есть уверенность, что эти функции действительно дадут обещанную в хелпе точность?

Автор: bems 18.10.2011, 00:22
Цитата(northener @  17.10.2011,  23:28 Найти цитируемый пост)
Есть уверенность, что эти функции действительно дадут обещанную в хелпе точность? 

http://www.transl-gunsmoker.ru/2010/11/blog-post_15.html Нет уверенности. Но можно сделать побольше итераций и таким образом решить эту проблему.

А QueryPerformanceCounter, как и Now, как и GetTickCount бессильны в случаях когда в середине измеряемого интервала активизируетсмя какой-нить другой тред и начинает делать что-то тяжелое

Автор: northener 18.10.2011, 00:53
Цитата(bems @  18.10.2011,  00:22 Найти цитируемый пост)
А QueryPerformanceCounter, как и Now, как и GetTickCount бессильны в случаях когда в середине измеряемого интервала активизируетсмя какой-нить другой тред и начинает делать что-то тяжелое 

Обоснуй! Про Now и GetTickCount я не спрашиваю. Только про QueryPerformanceCounter.

Автор: bems 18.10.2011, 02:20
ну прогони вот такую прогу и посмотри на результат
Код

program Project3;
{$APPTYPE CONSOLE}
uses
  windows, sysutils;

  procedure WriteInterval(ms: DWORD);
  var
    c1, c2: Int64;
  begin
    if not QueryPerformanceCounter(c1) then RaiseLastOsError;
    sleep(ms);
    if not QueryPerformanceCounter(c2) then RaiseLastOsError;
    writeln(c2 - c1);
  end;

begin
  WriteInterval(500);
  WriteInterval(1000);
  WriteInterval(2000);
  WriteInterval(5000);
  readln
end.


у меня она выдала
Цитата
1463520
2928468
5858403
14648058

Видно что результат прямопропорционален задержке в Sleep. Известно что эта функция делает вызвавший тред не планируемым как минимум на указанный интервал (ну есть неточность связанная с частотой таймера, но это в данном случае не важно). Большинство этого времени тред не выполняется. 
Представь что там не Sleep, а код, который ты пытаешься так профайлить. В середине этого кода, на на том же логическом процессоре начинает выполняться чужой поток (тз-за конца кванта времени отпущенного твоему потоку, или это высокоприоритетный поток и он вытесняет твой на этом основании). 
И QueryPerformanceCounter как ни в чем не бывало вернет тебе время, включающее выполнение чужого потока.

Автор: northener 18.10.2011, 02:39
Цитата(bems @  18.10.2011,  02:20 Найти цитируемый пост)
Видно что результат прямопропорционален задержке в Sleep. Известно что эта функция делает вызвавший тред не планируемым как минимум на указанный интервал (ну есть неточность связанная с частотой таймера, но это в данном случае не важно). Большинство этого времени тред не выполняется. 
Представь что там не Sleep, а код, который ты пытаешься так профайлить. В середине этого кода, на на том же логическом процессоре начинает выполняться чужой поток (тз-за конца кванта времени отпущенного твоему потоку, или это высокоприоритетный поток и он вытесняет твой на этом основании). 
И QueryPerformanceCounter как ни в чем не бывало вернет тебе время, включающее выполнение чужого потока.


Наверно мы говорим о разном.
Ты уж тогда приведи пример использования функций GetProcessTimes/GetThreadTimes в тех же условиях. А я уж сравню результаты.

P.S. Но "логгирование" тут уж никак ни при чём.

Автор: bems 18.10.2011, 02:45
Цитата(northener @  18.10.2011,  02:39 Найти цитируемый пост)
Ты уж тогда приведи пример использования функций GetProcessTimes/GetThreadTimes в тех же условиях. А я уж сравню результаты.

Сейчас


Цитата(northener @  18.10.2011,  02:39 Найти цитируемый пост)
Но "логгирование" тут уж никак ни при чём. 

А где о нем шла речь?

Автор: northener 18.10.2011, 02:52
Цитата(bems @  18.10.2011,  02:45 Найти цитируемый пост)
А где о нем шла речь?

В "некромантском " посте от 28.7.2011, 16:22
на который вы "поспешили ответить" 17.10.2011, 22:45 

Автор: bems 18.10.2011, 03:05
Как-то так
Код

program Project3;
{$APPTYPE CONSOLE}
uses
  windows, sysutils;

  procedure LoopDelay(ms: DWORD);
  var
    tc: DWORD;
  begin
    tc := GetTickCount;
    repeat until GetTickCount - tc >= ms;
  end;

  procedure WriteInterval(ms: DWORD; UseSleep: Boolean);
  var
    c, e: FileTime;
    kt1, kt2, ut1, ut2: ULARGE_INTEGER;
  begin
    if not GetThreadTimes(GetCurrentThread, c, e, FileTime(kt1), FileTime(ut1))
       then RaiseLastOsError;

    if UseSleep then Sleep(ms) else LoopDelay(ms);

    if not GetThreadTimes(GetCurrentThread, c, e, FileTime(kt2), FileTime(ut2))
       then RaiseLastOsError;
    writeln('User: ', ut2.QuadPart - ut1.QuadPart, '     Kernel: ', kt2.QuadPart - kt1.QuadPart);
  end;

begin
  WriteInterval(500, True);
  WriteInterval(500, False);
  writeln;

  WriteInterval(1000, True);
  WriteInterval(1000, False);
  writeln;

  WriteInterval(2000, True);
  WriteInterval(2000, False);
  writeln;
  
  WriteInterval(5000, True);
  WriteInterval(5000, False);
  readln
end.

результат:

Цитата
User: 0     Kernel: 0
User: 5148033     Kernel: 0

User: 0     Kernel: 0
User: 9048058     Kernel: 0

User: 0     Kernel: 0
User: 19188123     Kernel: 0

User: 0     Kernel: 0
User: 45240290     Kernel: 0

видим что в случае Sleep никакого выполнения не фиксируется, а в случае задержки циклом - фиксируется время, грубо пропорциональное времени задержки. То что грубо вина не только GetThreadTimes а еще и GetTickCount который тут постольку поскольку.

Добавлено через 1 минуту и 42 секунды
Цитата(northener @  18.10.2011,  02:52 Найти цитируемый пост)
на который вы "поспешили ответить" 17.10.2011, 22:45  
даже не представляю как я тут оказался smile

Автор: northener 18.10.2011, 03:31
Цитата(bems @  18.10.2011,  03:05 Найти цитируемый пост)
То что грубо вина не только GetThreadTimes а еще и GetTickCount который тут постольку поскольку.

А я ведь не об этом. То что GetTickCount имеет дискретность ~16мс это не секрет.
И прямая пропорциональность тоже не волшебство.
Я лишь хотел спросить о том, поддерживают ли функции GetProcessTimes/GetThreadTimes обещанную точность в 100 наносекунд?
Дело в том, что на предыдущей своей работе столкнулся с тем, что внешнее (и ну очень дорогое железо) никак не хочет принимать команды чаще чем через 16 мс. Но это бы ещё ничего. Но примерно раз через пять, оно принимало и выполняло команды с задержкой в 200-300 мс.
Только логгирование с помощью функции QueryPerformanceCounter мне помогло доказать начальству, что то железо, которое они купили за бешеные деньги ни как им не годится. 

Автор: bems 18.10.2011, 03:51
Цитата(northener @  18.10.2011,  00:53 Найти цитируемый пост)
Цитата(bems @  18.10.2011,  00:22 Найти цитируемый пост)
А QueryPerformanceCounter, как и Now, как и GetTickCount бессильны в случаях когда в середине измеряемого интервала активизируетсмя какой-нить другой тред и начинает делать что-то тяжелое 


Обоснуй! Про Now и GetTickCount я не спрашиваю. Только про QueryPerformanceCounter. 

Вот тут ты просил показать что QueryPerformanceCounter не выдерживает условия конкуренции тредов, а GetThreadTimes выдерживает. Я показал.
А твой пример со сторонним железом тут вообще не при чем, потому что не идет речь о том сколько же времени выполнялся код твоего процесса/потока, а только когда отреагировало железо.
Тут GetThreadTimes не поможет, но недостаток QueryPerformanceCounter остаётся: если твой тред вытеснят, то ты поставишь отметку времени завершения команды позже чем реально ответило железо.

Автор: northener 19.10.2011, 00:03
Цитата(bems @  18.10.2011,  03:51 Найти цитируемый пост)
А твой пример со сторонним железом тут вообще не при чем, потому что не идет речь о том сколько же времени выполнялся код твоего процесса/потока, а только когда отреагировало железо.

Ну в данном случае речь как раз шла о времени выполнения моего кода вкупе со временем выполнения функций/процедур, которые непосредственно работают с тем железом. А "те функции/процедуры" мне были даны в некоей/неких dll.

P.S. Собственно к железу у меня претензий не было.
Дали бы мне "непосредственный" доступ к нему, я скорее всего смог бы с ним справиться так как нужно было заказчику. 

Автор: bems 19.10.2011, 01:48
Ну собственно выполнение кода замерило бы, да.

Автор: Korod 24.10.2011, 12:06
Говорить о точности измерения временных интервалов в Винде - смех! Что  GetTick..., что Query..., что в стену - что об стену..

Автор: CROTishka 25.10.2011, 10:04
Цитата

Ещё вопрос, а как не задать память приложению, а узнать, сколько точно времени оно работало и сколько динамической памяти заняло. И если можно пример???

а что, профилировщики ещё не посоветовали?
лично я с делфи AQtime использую.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)