Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.65
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
#1

Измерение времени исполнения алгоритма через Clock() периодически равно 0 - C++

02.11.2009, 22:46. Просмотров 3022. Ответов 9
Метки нет (Все метки)

Здравствуйте!
Я в отчаянии
Была программа на C# и появилась необходимость перевести ее на С++. Но как переписать
System.Diagnostics.Stopwatch myStopWatch = new System.Diagnostics.Stopwatch();
myStopWatch.Start();
............
myStopWatch.Stop();
я так и не осилил. Необходимо выводить результат в милисекундах

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "stdafx.h"
#include <iostream>
#include "time.h"
#include <windows.h>
#include "conio.h"
using namespace std;
 
 
void Counting(int from, int To, double* & xx, double* & s, double* x, double* F, double h, double h1)
{
    double A;
    for (int i = from; i < 1.0 + To; i++)
    {
        for (int j = 0; j <= 9.0; j++)
        {
            xx[-10 + 10 * i + j] = x[i - 1] + j * h1;                    
            A = j * h1 / h;                    
            s[-10 + 10 * i + j] = F[i - 1] * (1.0 - A) + A * F[i];
        }
    }
}
 
 
long Res()
{
    int n = 30000;
    double h;
    double h1;
    int i;
    double* x = new double[1 + n];
    double* F = new double[1 + n];
    double* s = new double [10*n];
    double* xx = new double[10*n];
 
    h = 2.0 / n;
 
 
    for (i = 1; i <= 1.0 + n; i++)
    {
        x[i - 1] = -1.0 + i * h - h;
        F[i - 1] = 1 / (1.0 + 25.0 * x[i - 1] * x[i - 1]);
    }
    
    clock_t start,stop,myStopWatch;
    start=clock();
 
    h1 = h / 10.0;            
    Counting(1, n, xx, s, x, F, h, h1);
    stop = clock();
 
    myStopWatch = stop-start;
    delete []x;
    delete []xx;
    delete []s;
    delete []F;
 
    return myStopWatch;
}
 
 
 
int main()
{
    double d=0;
    int k;
    for (int i=0; i<1999; i++)
    {
        k=Res();
        cout<<k<<endl;
        d+=k;
    }
    d = d / 2000;
    cout<<d<<endl;
    getch();    
    return 0;
}
В чем конкретно проблема:
в~800 из 2000 запусков Res() возвращает 0, в оставшиеся запуски - ~16(ну вообщем достаточно ровные результаты)

Как бороться?

Заранее большое спасибо всем откликнувшимся
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.11.2009, 22:46
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Измерение времени исполнения алгоритма через Clock() периодически равно 0 (C++):

Замер времени работы функции через clock() - C++
Имеется некая функция, требуется замерить время её выполнения. Накидал такой код : #include &lt;iostream&gt; #include &lt;stdint.h&gt; ...

Определить в какой единице измерения времени считает clock()? - C++
Добрый день, очень прошу помощи :wall: Есть код, вот часть, работающая со временем измерения... Подскажите пожалуйста в какой единице...

Измерение времени - C++
while (Message.message!=WM_QUIT) { if(PeekMessage(&amp;Message, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&amp;Message); ...

Измерение времени - C++
DWORD dwStart, dwFinish, dwDif; dwStart=GetTickCount(); MatrixSum(SizeOfMatrix,Matrix,Matrix2,MatrixRes); dwFinish=GetTickCount(); ...

Измерение времени компиляции - C++
как узнать время компиляции исходного текста и размер памяти, которую програма использует

Измерение времени выполнения - C++
Подскажите пожалуйста как измерить время выполнения чего-то с наносекундной точностью. std::chrono::high_resolution_clock::time_point...

9
niXman
Эксперт С++
3139 / 1451 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.11.2009, 22:52 #2
http://msdn.microsoft.com/en-us/library/ms724408%28VS.85%29.aspx
1
Random
8 / 8 / 2
Регистрация: 25.11.2008
Сообщений: 32
02.11.2009, 22:55 #3
16 - это погрешность, т.е. скорее всего это тоже ноль
либо ошибка в программе, либо попробуйте зациклить свой алгоритм, выполнить его раз 100 или 1000
1
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
03.11.2009, 00:48  [ТС] #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "stdafx.h"
#include <iostream>
#include "time.h"
#include <windows.h>
#include "conio.h"
using namespace std;
 
 
void Counting(int from, int To, double* & xx, double* & s, double* x, double* F, double h, double h1)
{
    double A;
    for (int i = from; i < 1.0 + To; i++)
    {
        for (int j = 0; j <= 9.0; j++)
        {
            xx[-10 + 10 * i + j] = x[i - 1] + j * h1;                    
            A = j * h1 / h;                    
            s[-10 + 10 * i + j] = F[i - 1] * (1.0 - A) + A * F[i];
        }
    }
}
 
 
double Res()
{
    int n = 30000;
    double h;
    double h1;
    int i;
    double* x = new double[1 + n];
    double* F = new double[1 + n];
    double* s = new double [10*n];
    double* xx = new double[10*n];
 
    h = 2.0 / n;
 
 
    for (i = 1; i <= 1.0 + n; i++)
    {
        x[i - 1] = -1.0 + i * h - h;
        F[i - 1] = 1 / (1.0 + 25.0 * x[i - 1] * x[i - 1]);
    }
    
    LARGE_INTEGER start2;
    LARGE_INTEGER stop2;
    QueryPerformanceCounter(&start2);
 
    h1 = h / 10.0;            
    Counting(1, n, xx, s, x, F, h, h1);
 
    QueryPerformanceCounter(&stop2);
    delete []x;
    delete []xx;
    delete []s;
    delete []F;
 
    return (stop2.QuadPart-start2.QuadPart);
}
 
 
 
int main()
{
    double d=0;
    double k;
    for (int i=0; i<1999; i++)
    {
        k=Res();
        cout<<k<<endl;
        d+=k;
    }
    d = d / 2000;
    cout<<d<<endl;
    getch();    
    return 0;
}
Написал вот так вот.. Результаты около 24000-25000. Этому можно верить? Или в QueryPerformanceCounter тоже есть подвох?? (+ еще один дилетантский вопрос - а 25000 чего? микросекунд?)

p.s. Random,niXman спасибо!
0
Random
8 / 8 / 2
Регистрация: 25.11.2008
Сообщений: 32
03.11.2009, 10:44 #5
мне кажется, это не совсем верно. у вас получается, что вы 1999 раз засекаете время и потом его суммируете. вам нужно засекать время единожды, а алгоритм выполнять много раз
а что такое счетчик производительности я к сожалению не знаю
0
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
04.11.2009, 12:58  [ТС] #6
Написал вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "stdafx.h"
#include <iostream>
#include "time.h"
#include <windows.h>
#include "conio.h"
using namespace std;
 
 
void Counting(int from, int To, double* xx, double* s, double* x, double* F, double h, double h1)
{
        double A;
    for (int i = from; i < 1.0 + To; i++)
    {
                for (int j = 0; j <= 9.0; j++)
                {
                        xx[-10 + 10 * i + j] = x[i - 1] + j * h1;                    
                        A = j * h1 / h;                    
                        s[-10 + 10 * i + j] = F[i - 1] * (1.0 - A) + A * F[i];
                }
        }
}
 
 
double Res()
{
    int n = 30000;
    double h;
    double h1;
    int i;
    double* x = new double[1 + n];
    double* F = new double[1 + n];
    double* s = new double [10*n];
    double* xx = new double[10*n];
 
    h = 2.0 / n;
 
 
    for (i = 1; i <= 1.0 + n; i++)
    {
        x[i - 1] = -1.0 + i * h - h;
        F[i - 1] = 1 / (1.0 + 25.0 * x[i - 1] * x[i - 1]);
    }
 
    h1 = h / 10.0;      
    int c = -GetTickCount();
    for (i=0; i<1999;i++) 
       Counting(1, n, xx, s, x, F, h, h1);
    c+=GetTickCount();
    delete []x;
    delete []xx;
    delete []s;
    delete []F;
 
    return c;
}
 
 
 
int main()
{
        double k=Res();
        k/=2000;
        cout<<k<<endl;
        getch();        
        return 0;
}
Гуру, подскажите, оно действительно меряет время измерения функции? И меряет правильно? Я уже столько всего перепробовал, что ничему не верю

И еще,почему если в int c = GetTickCount() "c" сделать типа double, а не int - выводятся результаты в духе 2.14439е+006, а в int - 6-7. Так и должно быть?
0
CyBOSSeR
Эксперт С++
2308 / 1681 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
04.11.2009, 12:58 #7
Попробуй использовать GetThreadTimes, пример ниже:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
_int64 FileTimeToQuadWord(PFILETIME pft)
{
    return(Int64ShllMod32(pft->dwHighDateTime, 32) | pft->dwLowDateTime);
}
 
void PerformLongOperation ()
{
    FILETIME ftKernelTimeStart, ftKernelTimeEnd; 
    FILETIME ftUserTimeStart, ftUserTimeEnd; 
    FILETIME ftDummy;
 
    _int64 qwKernelTimeElapsed, qwUserTimeElapsed, qwTotalTimeElapsed;
 
    // получаем начальные показатели времени 
    GetThreadTimes(GetCurrentThread(), &ftDummy, &ftDummy,
                   &ftKernelTimeStart, &ftUserTimeStart);
 
    // здесь выполняем сложный алгоритм 
 
    // получаем конечные показатели времени
    GetThreadTimes(GetCurrentThread(), &ftDummy, &ftDummy,
                   &ftKernelTimeEnd, &ftUserTimeEnd);
 
    // получаем значении времени, затраченного на выполнение ядра и User, 
    // преобразуя начальные и конечные показатели времени из FILETIME 
    // в учетверенные слова, а затем вычитая начальные показатели из конечных 
    qwKernelTimeElapsed = FileTimeToQuadWord(&ftKernelTimeEnd) -
                          FileTimeToQuadWord(&ftKernelTimeStart);
 
    qwUserTimeElapsed = FileTimeToQuadWord(&ftUserTimeEnd) -
                        FileTimeToQuadWord(&ftUserTimeStart);
 
    // получаем общее время, складывая время выполнения ядра и User 
    qwTotalTimeElapsed = qwKernelTimeElapsed + qwUserTimeElapsed;
 
    // общее время хранится в qwTotalTimeElapsed
 
}
qwTotalTimeElapsed - время, выраженное в интервалах по 100 нс.
По поводу GetTickCount, цитата из книги Дж.Рихтер "Создание эффективных Win32 приложений ":
Иногда нужно знать, сколько времени затрачивает поток на выполнение той или иной операции. Многие в таких случаях пишут что-то вроде этого:
C++
1
2
3
4
5
6
7
8
// получаем стартовое время
 
DWORD dwStartTime = GetTickCount();
 
// здесь выполняем какой-нибудь сложный алгоритм 
// вычитаем стартовое время из текущего
 
DWORD dwElapsedTime = GetTickCount() - dwStartTime;
Этот код основан на простом допущении, что он не будет прерван. Но в операционной системе с вытесняющей многозадачностью никто не знает, когда поток получит процессорное время, и результат будет сильно искажен.
2
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
04.11.2009, 13:01  [ТС] #8
CyBOSSeR,
Спасибо за ответ!
Пока писал прошлое сообщение меня вдруг осенило и переписал вроде как с виду адекватно работающее измерение + достаточно простое. Не могли бы Вы сказать, можно ли так считать, как в отредактированном выше моем посте.
0
CyBOSSeR
Эксперт С++
2308 / 1681 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
04.11.2009, 14:53 #9
Цитата Сообщение от Логос Посмотреть сообщение
Не могли бы Вы сказать, можно ли так считать, как в отредактированном выше моем посте.
Ты имеешь ввиду этот:
C++
1
2
3
4
5
6
int c = -GetTickCount();
 
for (i=0; i<1999;i++) 
  Counting(1, n, xx, s, x, F, h, h1);
 
c+=GetTickCount();
?
Если уж все таки решил использовать GetTickCount(), то нужно немного переписать этот фрагмент. А то вот такая конструкции:
C++
1
2
3
int c = -GetTickCount();
//...
c = +GetTickCount();
лично у меня вызывает недоумение.
Я бы написал так:
C++
1
2
3
4
5
6
DWORD start_time = GetTickCount();
 
for (i=0; i<1999;i++) 
  Counting(1, n, xx, s, x, F, h, h1);
 
DWORD execution_time = GetTickCount() - start_time;
Результат будет одним и тем же, но просто это выглядит более логично.
0
serrg
68 / 68 / 2
Регистрация: 02.07.2010
Сообщений: 228
21.07.2010, 21:51 #10
Может тема и устарела, но кому-нибудь может понадобиться. Надо брать не 2500 а значение из QueryPerformanceFrequency(*LARGE_INTEGER) работает аналогично QueryPerformanceCounter().
а GetTickCount() это системный тик и срабатывает один раз в 15 с хвостиком милисекунд, поэтому он не точен.
Попутный вопрос, может кто из экспертов знает как получает этот счетчик производительности?
0
21.07.2010, 21:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2010, 21:51
Привет! Вот еще темы с ответами:

Измерение времени переключения контекста - C++
Кто может подсказать, какими способами это возможно реализовать в Windows? Есть ли способы, не прибегая к ассемблеру? Есть мысли на...

Измерение времени работы кода - C++
Нужно подсчитать время выполнения кода. данный отрывок сортирует массив. если размер массива маленький, то выводит 0. При большом размере...

Измерение времени выполнения потока - C++
#include &quot;stdafx.h&quot; #include &lt;clocale&gt; #include &lt;math.h&gt; #include &lt;windows.h&gt; int l, m, n, geo, sum; DWORD WINAPI proizv...

Динамически создаваемый масссив, ошибка времени исполнения - C++
Попытался создать двумерный массив. Неудачно. Падает и не могу понять причину. #include &lt;iostream&gt; using namespace std; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru