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

RDTSC или как замерять количество тактов CPU на некоторые вычисления? - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 49, средняя оценка - 4.80
returnless
25 / 25 / 3
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 09:18     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #1
пока мерю так. но что-то мне подсказывает 677 тактов на вычисление простой длины вектора слишком много. два подряд умножение уже 1800+ тактов. как вообще правильно замерять подобные вещи? как это отцы делают?

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
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() 
{
 
    unsigned clock = 0;
    float x = 1.0f;
    float y = 2.0f;
    float z = 3.0f;
    float length = 0.0f;
 
    __asm rdtsc;
    __asm mov [clock], eax;
 
    // вычисляем длину вектора
    length = sqrtf(x*x + y*y + z*z);
 
    __asm rdtsc;
    __asm sub eax,[clock];
    __asm mov [clock], eax;
 
    // количество тактов процессора на вычисления
    printf("%u", clock);
    system("pause");
 
    return 0;
}
помогите плиз.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2012, 09:18     RDTSC или как замерять количество тактов CPU на некоторые вычисления?
Посмотрите здесь:

Замер времени(тактов процессора) выполнения процедуры C++
Borland c 5.02 при запуске по шагам (F8) вылетает окошко CPU c кодом АСМ как его убрать? C++
C++ Главная функция (вводит некоторые значения и передает их и ссылки на некоторые переменные в функцию)
C++ как в слове поменять некоторые буквы местами?
C++ Количество нулевых, или положительных, или отрицательных элементов в двумерном массиве
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nexen
12.08.2012, 09:59
  #2

Не по теме:

Цитата Сообщение от returnless Посмотреть сообщение
677 тактов на вычисление простой длины вектора слишком много. два подряд умножение уже 1800+ тактов.
Что-то я не понял. Так "много" или "мало"?

returnless
12.08.2012, 10:36  [ТС]
  #3

Не по теме:

Что-то я не понял. Так "много" или "мало"?
слишком много

grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
12.08.2012, 12:02     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #4
returnless, заверни измерения целиком в цикл, хотя бы на 2 итерации (ну или больше), и сравни минимальный и максимальный результаты.
returnless
25 / 25 / 3
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 12:49  [ТС]     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #5
сделал так, кроме того запустил release версию она показала 12-19 тактов. теперь думаю норм.
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
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
int main() 
{
 
    unsigned clock = 0;
    float x = 1.0f;
    float y = 2.0f;
    float z = 3.0f;
    float length = 0.0f;
    int average = 0;
 
    for (int i = 0; i<10; i++) 
    {
    __asm rdtsc;
    __asm mov [clock], eax;
 
    // вычисляем длину вектора
    length = sqrtf(x*x + y*y + z*z);
 
 
    __asm rdtsc;
    __asm sub eax,[clock];
    __asm mov [clock], eax;
 
    // количество тактов процессора на вычисления
    printf("pass %u clock %u\n", i, clock);
    average += clock;
    };
    printf("average clock %u\n", (int)(average / i));
 
    system("pause");
 
    return 0;
}
еще вопрос как мне переделать вот этот квадратный корень на msvc ?
C++
1
2
3
4
5
6
7
8
9
//5 cycles (11 bits precision)
inline float very_fast_sqrt(float f) {
    asm("movss  (%%eax), %%xmm0;"
        "rsqrtss %%xmm0, %%xmm0;"
        "rcpss   %%xmm0, %%xmm0;"
        "movss   %%xmm0, (%%eax);"
        ::"a"(&f):"xmm0","memory");
    return f;
}
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
12.08.2012, 13:31     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #6
Цитата Сообщение от returnless Посмотреть сообщение
сделал так, кроме того запустил release версию она показала 12-19 тактов. теперь думаю норм.
Как бы не оказалось, что компилятор выбросил "ненужные" вычисления или не сократил их объём. В ассемблерный листинг смотрел?

Добавлено через 16 минут
Цитата Сообщение от returnless Посмотреть сообщение
еще вопрос как мне переделать вот этот квадратный корень на msvc ?
C++
1
2
3
4
5
6
7
8
9
inline
float very_fast_sqrt(float f)
{
    __asm movss   xmm0, [f];
    __asm rsqrtss xmm0, xmm0;
    __asm rcpss   xmm0, xmm0;
    __asm movss   [f], xmm0;
    return f;
}
returnless
25 / 25 / 3
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 13:40  [ТС]     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #7
В ассемблерный листинг смотрел?
еще нет, я не настолько прошареный что бы там чего-то понимать(
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
12.08.2012, 13:42     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #8
Цитата Сообщение от returnless Посмотреть сообщение
еще нет, я не настолько прошареный что бы там чего-то понимать(
Ну хотя бы найти в нём свои rdtsc и посмотреть, что расположено между ними.
returnless
25 / 25 / 3
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 14:41  [ТС]     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #9
да уж. выходит что если вычисленная длина length нигде не используется то компилятор просто выкидывает эти вычисления
Assembler
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
    rdtsc
 
; 35   :    __asm mov [clock], eax;
 
    mov DWORD PTR _clock$[esp+16], eax
 
; 36   : 
; 37   :    // вычисляем длину вектора
; 38   :    length = sqrtf (x*x + y*y + z*z);
; 39   : 
; 40   : 
; 41   :    __asm rdtsc;
 
    rdtsc
 
; 42   :    __asm sub eax,[clock];
 
    sub eax, DWORD PTR _clock$[esp+16]
 
; 43   :    __asm mov [clock], eax;
 
    mov DWORD PTR _clock$[esp+16], eax
 
; 44   : 
; 45   :    // количество тактов процессора на вычисления
; 46   :    printf("pass %u clock %u\n", i, clock);
 
    mov edi, DWORD PTR _clock$[esp+16]
    push    edi
    push    esi
    push    OFFSET FLAT:??_C@_0BC@LCNJJCII@pass?5?$CFu?5clock?5?$CFu?6?$AA@
    call    _printf
    add esp, 12                 ; 0000000cH
сделал вывод длины чтобы он ее не удалял, вычисление идет через стандартную sqrtf
еще инициализацию x.y.z повесил на рандом. чтобы компилятор не загонял x*x + y*y + z*z в const segment.

Assembler
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
77
78
79
80
81
82
83
27   :  float length = 0.0f;
; 28   :    
; 29   :    int average = 0;
; 30   : 
; 31   :    for (int i = 0; i<10; i++) 
 
    xor esi, esi
    mov DWORD PTR tv162[esp+32], edx
    fild    DWORD PTR tv162[esp+32]
    fld ST(0)
    fmul    ST(0), ST(1)
    fld DWORD PTR _y$[esp+32]
    fmul    DWORD PTR _y$[esp+32]
    faddp   ST(1), ST(0)
    fld DWORD PTR _x$[esp+32]
    fmul    DWORD PTR _x$[esp+32]
 
; 36   : 
; 37   :    // вычисляем длину вектора
; 38   :    length = sqrtf (x*x + y*y + z*z);
 
    faddp   ST(1), ST(0)
    fsqrt
    fstp    DWORD PTR tv174[esp+32]
    fstp    ST(0)
    npad    5
$L1648:
 
; 32   :    {
; 33   :    //length = x + y + z;
; 34   :    __asm rdtsc;
 
    rdtsc
 
; 35   :    __asm mov [clock], eax;
 
    mov DWORD PTR _clock$[esp+32], eax
 
; 39   : 
; 40   : 
; 41   :    __asm rdtsc;
 
    rdtsc
 
; 42   :    __asm sub eax,[clock];
 
    sub eax, DWORD PTR _clock$[esp+32]
 
; 43   :    __asm mov [clock], eax;
 
    mov DWORD PTR _clock$[esp+32], eax
 
; 44   : 
; 45   :    // количество тактов процессора на вычисления
; 46   :    printf("pass %u clock %u result %f\n", i, clock, length);
 
    fld DWORD PTR tv174[esp+32]
    mov edi, DWORD PTR _clock$[esp+32]
    sub esp, 8
    fstp    QWORD PTR [esp]
    push    edi
    push    esi
    push    OFFSET FLAT:??_C@_0BM@MNCMCBNO@pass?5?$CFu?5clock?5?$CFu?5result?5?$CFf?6?$AA@
    call    _printf
    add esp, 20                 ; 00000014H
 
; 47   : 
; 48   :    average += clock;
 
    add ebx, edi
    inc esi
    cmp esi, 10                 ; 0000000aH
    jl  SHORT $L1648
 
; 49   :    };
; 50   :    printf("average clock %u\n", (int)(average / i));
 
    mov eax, ebx
    cdq
    idiv    esi
    push    eax
    push    OFFSET FLAT:??_C@_0BC@EFNJMOEO@average?5clock?5?$CFu?6?$AA@
    call    _printf
а тут я вижу что вычисления вообще идут выше блока с rdtsc и между двух rdtsc вообще ничего нет. что за ерунда? почему компилятор меняет порядок выполнения Оо?
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
12.08.2012, 14:46     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #10
Цитата Сообщение от returnless Посмотреть сообщение
а тут я вижу что вычисления вообще идут выше блока с rdtsc и между двух rdtsc вообще ничего нет. что за ерунда? почему компилятор меняет порядок выполнения Оо?
Да, такое бывает. В GCC для предотвращения этого используется asm volatile. Как с этим бороться в MSVC я не знаю, но, возможно, тоже что-то есть.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2012, 14:54     RDTSC или как замерять количество тактов CPU на некоторые вычисления?
Еще ссылки по теме:

C++ Написать программу вычисления площади треугольники или квадрата или трапеции
C++ Замер количества тактов исполнения через rdtsc()
C++ Можно ли штатными средствами С++ замерять количество тиков процессора?

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

Или воспользуйтесь поиском по форуму:
returnless
25 / 25 / 3
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 14:54  [ТС]     RDTSC или как замерять количество тактов CPU на некоторые вычисления? #11
выключил оптимизацию теперь порядок нормальный.
Assembler
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
77
78
79
80
81
82
83
; 30   : 
; 31   :    for (int i = 0; i<10; i++) 
 
    mov DWORD PTR _i$1647[ebp], 0
    jmp SHORT $L1648
$L1649:
    mov edx, DWORD PTR _i$1647[ebp]
    add edx, 1
    mov DWORD PTR _i$1647[ebp], edx
$L1648:
    cmp DWORD PTR _i$1647[ebp], 10      ; 0000000aH
    jge SHORT $L1650
 
; 32   :    {
; 33   :    //length = x + y + z;
; 34   :    __asm rdtsc;
 
    rdtsc
 
; 35   :    __asm mov [clock], eax;
 
    mov DWORD PTR _clock$[ebp], eax
 
; 36   : 
; 37   :    // вычисляем длину вектора
; 38   :    length = sqrtf (x*x + y*y + z*z);
 
    fld DWORD PTR _x$[ebp]
    fmul    DWORD PTR _x$[ebp]
    fld DWORD PTR _y$[ebp]
    fmul    DWORD PTR _y$[ebp]
    faddp   ST(1), ST(0)
    fld DWORD PTR _z$[ebp]
    fmul    DWORD PTR _z$[ebp]
    faddp   ST(1), ST(0)
    push    ecx
    fstp    DWORD PTR [esp]
    call    _sqrtf
    add esp, 4
    fstp    DWORD PTR _length$[ebp]
 
; 39   : 
; 40   : 
; 41   :    __asm rdtsc;
 
    rdtsc
 
; 42   :    __asm sub eax,[clock];
 
    sub eax, DWORD PTR _clock$[ebp]
 
; 43   :    __asm mov [clock], eax;
 
    mov DWORD PTR _clock$[ebp], eax
 
; 44   : 
; 45   :    // количество тактов процессора на вычисления
; 46   :    printf("pass %u clock %u result %f\n", i, clock, length);
 
    fld DWORD PTR _length$[ebp]
    sub esp, 8
    fstp    QWORD PTR [esp]
    mov eax, DWORD PTR _clock$[ebp]
    push    eax
    mov ecx, DWORD PTR _i$1647[ebp]
    push    ecx
    push    OFFSET FLAT:$SG1651
    call    _printf
    add esp, 20                 ; 00000014H
 
; 47   : 
; 48   :    average += clock;
 
    mov edx, DWORD PTR _average$[ebp]
    add edx, DWORD PTR _clock$[ebp]
    mov DWORD PTR _average$[ebp], edx
 
; 49   :    };
 
    jmp SHORT $L1649
$L1650:
 
; 50   :    printf("average clock %u\n", (int)(average / i));
170-190 тактов. плин.
Yandex
Объявления
12.08.2012, 14:54     RDTSC или как замерять количество тактов CPU на некоторые вычисления?
Ответ Создать тему
Опции темы

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