2014 dxdy logo

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

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




 
 Таймер в с++
Сообщение26.12.2006, 19:59 
Подскажите откуда взять и как использовать таймер в c++

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

 
 
 
 
Сообщение26.12.2006, 20:17 
Можно использовать time.h Гляньте описание, функция используется clock() - возвращает, кажись, количество тактов с начала работы программы, а константа CLK_TCK соответствует количеству тактов в секунду. Одним словом, лучше посмотрите справку по time.h.

 
 
 
 
Сообщение26.12.2006, 22:57 
Большое спасибо

 
 
 
 Re: Таймер в с++
Сообщение27.12.2006, 15:45 
matematikFromMati писал(а):
Подскажите откуда взять и как использовать таймер в c++

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

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

 
 
 
 
Сообщение28.12.2006, 21:17 
о фактическом времени выполнения операции

 
 
 
 
Сообщение28.12.2006, 22:07 
Вот очень удобный класс таймера - уже не помню откуда взялся:), но пользуюсь уже давно.
Измерение времени до милисекунд
Пример использования -
Код:
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 
matematikFromMati писал(а):
о фактическом времени выполнения операции

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

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


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

 
 
 
 
Сообщение31.12.2006, 12:50 
VLarin - спасибо за помощь - задача уже сдана

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

 
 
 
 
Сообщение16.01.2007, 10:09 
VLarin писал(а):
Ну как - несмотря на это можно оценить примерное время выполнения:)

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

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

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

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

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

 
 
 
 
Сообщение16.01.2007, 10:28 
zbl писал(а):
Одного единственного запуска с наперёд известными входными данными?


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

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

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

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

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

 
 
 
 
Сообщение16.01.2007, 14:11 
Во-первых, нужно разделять отладку и оптимизацию. Тогда все станет на свои места.
В тексте я имел ввиду именно оптимизацию применительно к малым частям кода и всего кода в целом. И все, что было написано на мой взгляд является очевидным:)

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

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

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

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

 
 
 
 
Сообщение18.01.2007, 05:40 
Аватара пользователя
Код:
#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 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group