2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Таймер в с++
Сообщение26.12.2006, 19:59 


07/01/06
26
Подскажите откуда взять и как использовать таймер в c++

в задании нужно вычислить время копирования массива

 Профиль  
                  
 
 
Сообщение26.12.2006, 20:17 


07/02/06
96
Можно использовать time.h Гляньте описание, функция используется clock() - возвращает, кажись, количество тактов с начала работы программы, а константа CLK_TCK соответствует количеству тактов в секунду. Одним словом, лучше посмотрите справку по time.h.

 Профиль  
                  
 
 
Сообщение26.12.2006, 22:57 


07/01/06
26
Большое спасибо

 Профиль  
                  
 
 Re: Таймер в с++
Сообщение27.12.2006, 15:45 
Заслуженный участник


14/12/06
881
matematikFromMati писал(а):
Подскажите откуда взять и как использовать таймер в c++

в задании нужно вычислить время копирования массива

О каком из трёх времён копирования массива (real, user, sys) идёт речь в задании?

 Профиль  
                  
 
 
Сообщение28.12.2006, 21:17 


07/01/06
26
о фактическом времени выполнения операции

 Профиль  
                  
 
 
Сообщение28.12.2006, 22:07 


13/09/05
153
Москва
Вот очень удобный класс таймера - уже не помню откуда взялся:), но пользуюсь уже давно.
Измерение времени до милисекунд
Пример использования -
Код:
TimeCounter timer;
timer.Start();
...................
timer.Stop();
std::cout << timer;



TimeCounter.h-------------------------------------------------------------------------------------------
Код:
// TimeCounter.h

#ifndef __TIMECOUNTER222__H__
#define __TIMECOUNTER222__H__

#include <iostream>

// #include <cassert>

//////////////////////////////////////////
/// Допустимые значения приоритета потока:
/// THREAD_PRIORITY_HIGHEST
/// THREAD_PRIORITY_ABOVE_NORMAL
/// THREAD_PRIORITY_NORMAL
/// THREAD_PRIORITY_BELOW_NORMAL
/// THREAD_PRIORITY_LOWEST
//////////////////////////////////////////

class TimeCounter
{
friend std::ostream& operator<<(std::ostream& out, TimeCounter& cntr);
public:

   TimeCounter() {started=false; stopped=false;}
   void Start();
   void Start(int nPriority);
   void Stop();
   double timeElapsed() const;
   bool getStarted() const {return started;}
   bool getStopped() const {return stopped;}
   int getNewPriority() const {return new_priority;}
   ~TimeCounter();

protected:

   int new_priority;
   int old_priority;
   bool started;
   bool stopped;
   double tBefore, tAfter, i64PerfFrequency;
    double tWord;

};

#endif


TimeCounter.cpp-------------------------------------------------------------------------------------------
Код:
#include "stdafx.h"
#include "TimeCounter.h"
#include <windows.h>

void TimeCounter::Start()
{
//   assert(!started);
   started=true;
   stopped=false;
   new_priority=0;

   LARGE_INTEGER pf;
    QueryPerformanceFrequency(&pf);
   i64PerfFrequency = pf.QuadPart;
    Sleep(0);
    QueryPerformanceCounter(&pf);
   tBefore = pf.QuadPart;
}

void TimeCounter::Start(int nPriority)
{
//   assert(!started);
   started=true;
   stopped=false;
   new_priority=nPriority;
   old_priority=GetThreadPriority(GetCurrentThread());
   SetThreadPriority(GetCurrentThread(),new_priority);

   LARGE_INTEGER pf;
    QueryPerformanceFrequency(&pf);
   i64PerfFrequency = pf.QuadPart;
    Sleep(0);
   QueryPerformanceCounter(&pf);
   tBefore = pf.QuadPart;
}

void TimeCounter::Stop()
{
//   assert(started);
   LARGE_INTEGER tAfter1;
   QueryPerformanceCounter(&tAfter1);
   tAfter = tAfter1.QuadPart;

   tWord = tAfter - tBefore;
   tWord /= i64PerfFrequency;
   if (new_priority)
      SetThreadPriority(GetCurrentThread(),old_priority);
   started=false;
   stopped=true;
}
   
double TimeCounter::timeElapsed() const
{
   LARGE_INTEGER tempAfter;
   double tempWord;

   if (started)
   {
      QueryPerformanceCounter(&tempAfter);
      tempWord = tempAfter.QuadPart - tBefore;
      tempWord /= i64PerfFrequency;

      return tempWord;
   }
   if (stopped)
      return tWord;
   
   return 0.;
}

TimeCounter::~TimeCounter()
{
   if (new_priority)
      SetThreadPriority(GetCurrentThread(),old_priority);
}

std::ostream& operator<<(std::ostream& out, TimeCounter& cntr)
{
   double fsec = cntr.timeElapsed();
   int hour = int(fsec/3600.);
   double fmin = fsec-3600.*double(hour);
   int min = int(fmin/60.);
   double sec = fmin-60.*double(min);
   out<<"Time elapsed: "<<hour<<" h. "<<min<<" min. "<<sec<<" sec."<<std::endl;
//   out<<"Calculated with priority number: ";
//   if (cntr.getNewPriority())
//      out<<cntr.getNewPriority()<<endl;
//   else
//      out<<GetThreadPriority(GetCurrentThread())<<endl;
   return out;
}

 Профиль  
                  
 
 
Сообщение29.12.2006, 12:28 
Заслуженный участник


14/12/06
881
matematikFromMati писал(а):
о фактическом времени выполнения операции

Интересно, а зачем могло потребоваться знать это время, если при следущем запуске программы оно будет иным, а распределено оно не только не по Гауссу, а вообще дьявольки мудро?

 Профиль  
                  
 
 
Сообщение29.12.2006, 15:09 


13/09/05
153
Москва
zbl писал(а):
Интересно, а зачем могло потребоваться знать это время, если при следущем запуске программы оно будет иным, а распределено оно не только не по Гауссу, а вообще дьявольки мудро?


Ну как - несмотря на это можно оценить примерное время выполнения:)
Время-то разное, но порядок величин тот же, особенно когда время выполнения ни несколько милисекунд, а несколько минут.

 Профиль  
                  
 
 
Сообщение31.12.2006, 12:50 


07/01/06
26
VLarin - спасибо за помощь - задача уже сдана

zbl вы знаете что такое KISS? :D

 Профиль  
                  
 
 
Сообщение16.01.2007, 10:09 
Заслуженный участник


14/12/06
881
VLarin писал(а):
Ну как - несмотря на это можно оценить примерное время выполнения:)

Одного единственного запуска с наперёд известными входными данными?
Я таки тащусь от глубокого осознания меры возможной пользы подобного мероприятия...
Типа, вопрос ставился так: запустим программу и сходим вниз попить кофейку; если, когда вернёмся, не сосчитает ещё, то попробуем заменить метод скорейшего спуска на Simulated Annealing?

Ещё интереснее стало; к чему вся эта задача-то была? по какому поводу она возникла из дальнего небытия, так сказать?
Если это контрольная задача какая-нибудь, то что именно с её помощью предполагалось проконтролировать -- вот в чём вопрос? выявить неумение пользоваться утилитами операционной системы вроде оной time в UNIX?
А, если она "из реальной жизни", то таки просто жуть как интересно, в какой отрасли нашей многострадальной промышленности востребовано ПО, требующее для своего производства решения подобного рода задач...

Добавлено спустя 6 минут:

matematikFromMati писал(а):
zbl вы знаете что такое KISS? :D

А Вы это как произносите: "KISS" или "KIS,S" ?

 Профиль  
                  
 
 
Сообщение16.01.2007, 10:28 


13/09/05
153
Москва
zbl писал(а):
Одного единственного запуска с наперёд известными входными данными?


Ну почему же, все зависит от того, что хотим оптимизировать.
Если маленькую функцию - запускаем в ОЧЕНЬ большом цикле, исходные данные генерим рандомайзом. Если задачу в целом - то запускаем один раз и сравниваем разные варианты.
Время можно оценить как угодно, хоть тем же time, а можно использовать готовый класс таймера, на мой взгляд достаточно удобный для этой цели.

 Профиль  
                  
 
 
Сообщение16.01.2007, 11:37 
Заслуженный участник


14/12/06
881
VLarin писал(а):
Ну почему же, все зависит от того, что хотим оптимизировать.
Если маленькую функцию - запускаем в ОЧЕНЬ большом цикле, исходные данные генерим рандомайзом.

Например, пишем подпрограмму обращения матрицы, генерим рандомайзом входные матрицы и смотрим время с точностью до порядка? если день, а не минута, то видно что-то мы напутали там с реализацией...
Стоп; в нашем коде баг, который вешает всё, если на диагонали стоят одни нули...
Нука, прикинем вероятность того, что мы его сможем найти нашим рандомайзным способом... ет.. маловато однако получается...

VLarin писал(а):
Если задачу в целом - то запускаем один раз и сравниваем разные варианты.

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

 Профиль  
                  
 
 
Сообщение16.01.2007, 14:11 


13/09/05
153
Москва
Во-первых, нужно разделять отладку и оптимизацию. Тогда все станет на свои места.
В тексте я имел ввиду именно оптимизацию применительно к малым частям кода и всего кода в целом. И все, что было написано на мой взгляд является очевидным:)

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

Если код считает несколько минут-часов, то точная оценка до милисекунд ни к чему, но в этом случае таймер можно использовать для автоматизации оптимизации - т.е. написать код, который бы запускал различные варинты функций с различными исходными данными, оценивал бы время выполнения каждого в отдельности, и выводил время выполнения каждого в некий файл. Зачем что-то делать в ручную, если можно программно?:)
Тем более, что можно запустить на одном компе, работать на другом. Ну это так, общие идее и соображения:)

 Профиль  
                  
 
 
Сообщение17.01.2007, 10:02 
Заслуженный участник


14/12/06
881
VLarin писал(а):
Зачем что-то делать в ручную, если можно программно?:)
Тем более, что можно запустить на одном компе, работать на другом. Ну это так, общие идее и соображения:)

Хоккей, убедили.
Я сам так часто делаю -- чего пристал... не выспался.
Оптимизация, однако, от отладки мало чем отличается в данном случае; а автоматизировать подобную работу много эффективнее с помощью Unit Testing плюс стандартных средств ОС.
Пошёл спать...

 Профиль  
                  
 
 
Сообщение18.01.2007, 05:40 
Аватара пользователя


09/05/06
115
Код:
#if !defined _TIMER_H_
#define _TIMER_H_

inline unsigned __int64 GetCycleCount(void) {
   _asm   _emit 0x0F
   _asm   _emit   0x31
}

class KTimer
{
unsigned __int64 m_startcycle;
public:
unsigned __int64 m_overhead;
KTimer() {
   m_overhead = 0;
   Start();
   m_overhead = Stop();
}

void Start(void) {
   m_startcycle = GetCycleCount();
}

unsigned __int64 Stop(void) {
   return GetCycleCount() - m_startcycle - m_overhead;
}
};

#endif
Вот ещё один класс таймера. Использовать так:
Код:
   _BOOLEAN bEnoughData;
   KTimer timer;
   unsigned cpuspeed10, time;

   Memo.term_echo("Reset all parameters to start parameter settings.\r\n");   
   timer.Start();
   Sleep(1000);
   cpuspeed10 = (unsigned)(timer.Stop()/100000);
   Memo.term_echo("CPU speed %d.%02d mhz\r\n", cpuspeed10/10, cpuspeed10 % 10);
Это пример, который тактовую частоту CPU вычисляет.

Класс взят из замечательной книжки Фень Юаня "Программирование графики для Windows". Рекомендуется всем, кто занимается низкоуровневым (системным) программированием в Windows.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group