Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.65
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
02.11.2009, 22:46     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #1
Здравствуйте!
Я в отчаянии
Была программа на 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(ну вообщем достаточно ровные результаты)

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

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

Измерение времени выполнения потока C++
C++ Измерение времени компиляции
Измерение времени C++
C++ Измерение времени
C++ Реализовать стратегий обработки возможных ошибок времени исполнения
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
02.11.2009, 22:52     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #2
http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx
Random
8 / 8 / 2
Регистрация: 25.11.2008
Сообщений: 32
02.11.2009, 22:55     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #3
16 - это погрешность, т.е. скорее всего это тоже ноль
либо ошибка в программе, либо попробуйте зациклить свой алгоритм, выполнить его раз 100 или 1000
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
03.11.2009, 00:48  [ТС]     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #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 спасибо!
Random
8 / 8 / 2
Регистрация: 25.11.2008
Сообщений: 32
03.11.2009, 10:44     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #5
мне кажется, это не совсем верно. у вас получается, что вы 1999 раз засекаете время и потом его суммируете. вам нужно засекать время единожды, а алгоритм выполнять много раз
а что такое счетчик производительности я к сожалению не знаю
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
04.11.2009, 12:58  [ТС]     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #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. Так и должно быть?
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
04.11.2009, 12:58     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #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;
Этот код основан на простом допущении, что он не будет прерван. Но в операционной системе с вытесняющей многозадачностью никто не знает, когда поток получит процессорное время, и результат будет сильно искажен.
Логос
0 / 0 / 0
Регистрация: 02.11.2009
Сообщений: 8
04.11.2009, 13:01  [ТС]     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #8
CyBOSSeR,
Спасибо за ответ!
Пока писал прошлое сообщение меня вдруг осенило и переписал вроде как с виду адекватно работающее измерение + достаточно простое. Не могли бы Вы сказать, можно ли так считать, как в отредактированном выше моем посте.
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
04.11.2009, 14:53     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #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;
Результат будет одним и тем же, но просто это выглядит более логично.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2010, 21:51     Измерение времени исполнения алгоритма через Clock() периодически равно 0
Еще ссылки по теме:

C++ Измерение времени переключения контекста
Измерение времени работы кода C++
C++ Динамически создаваемый масссив, ошибка времени исполнения

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

Или воспользуйтесь поиском по форуму:
serrg
 Аватар для serrg
68 / 68 / 2
Регистрация: 02.07.2010
Сообщений: 228
21.07.2010, 21:51     Измерение времени исполнения алгоритма через Clock() периодически равно 0 #10
Может тема и устарела, но кому-нибудь может понадобиться. Надо брать не 2500 а значение из QueryPerformanceFrequency(*LARGE_INTEGER) работает аналогично QueryPerformanceCounter().
а GetTickCount() это системный тик и срабатывает один раз в 15 с хвостиком милисекунд, поэтому он не точен.
Попутный вопрос, может кто из экспертов знает как получает этот счетчик производительности?
Yandex
Объявления
21.07.2010, 21:51     Измерение времени исполнения алгоритма через Clock() периодически равно 0
Ответ Создать тему
Опции темы

Текущее время: 01:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru