26 / 26 / 0
Регистрация: 05.08.2012
Сообщений: 83
1

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

12.08.2012, 09:18. Показов 17236. Ответов 10
Метки нет (Все метки)

пока мерю так. но что-то мне подсказывает 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;
}
помогите плиз.
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.08.2012, 09:18
Ответы с готовыми решениями:

Замер количества тактов исполнения через rdtsc()
по идее rdtsc(); выдает кол-во тактов, т.е. т2-т1 выдаст затраченное кол-во тактов на том или ином...

Можно ли штатными средствами С++ замерять количество тиков процессора?
Хочу узнать, сколько тактов процессора прошло с начала запуска приложения. Возможно? В WinApi для...

Количество тактов
народ помогите написать программу, которая подсчитывает количество тактов процессора, которые нужны...

Количество тактов, затрачиваемых программой MASM
Как узнать количество тактов, которое тратится на программу? .386 .model flat, stdcall option...

10
nexen
12.08.2012, 09:59
  #2

Не по теме:

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

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

Не по теме:

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

0
Эксперт С++
2374 / 1658 / 279
Регистрация: 29.05.2011
Сообщений: 3,387
12.08.2012, 12:02 4
returnless, заверни измерения целиком в цикл, хотя бы на 2 итерации (ну или больше), и сравни минимальный и максимальный результаты.
1
26 / 26 / 0
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 12:49  [ТС] 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;
}
0
Эксперт С++
2374 / 1658 / 279
Регистрация: 29.05.2011
Сообщений: 3,387
12.08.2012, 13:31 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;
}
1
26 / 26 / 0
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 13:40  [ТС] 7
В ассемблерный листинг смотрел?
еще нет, я не настолько прошареный что бы там чего-то понимать(
0
Эксперт С++
2374 / 1658 / 279
Регистрация: 29.05.2011
Сообщений: 3,387
12.08.2012, 13:42 8
Цитата Сообщение от returnless Посмотреть сообщение
еще нет, я не настолько прошареный что бы там чего-то понимать(
Ну хотя бы найти в нём свои rdtsc и посмотреть, что расположено между ними.
1
26 / 26 / 0
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 14:41  [ТС] 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 вообще ничего нет. что за ерунда? почему компилятор меняет порядок выполнения Оо?
0
Эксперт С++
2374 / 1658 / 279
Регистрация: 29.05.2011
Сообщений: 3,387
12.08.2012, 14:46 10
Цитата Сообщение от returnless Посмотреть сообщение
а тут я вижу что вычисления вообще идут выше блока с rdtsc и между двух rdtsc вообще ничего нет. что за ерунда? почему компилятор меняет порядок выполнения Оо?
Да, такое бывает. В GCC для предотвращения этого используется asm volatile. Как с этим бороться в MSVC я не знаю, но, возможно, тоже что-то есть.
1
26 / 26 / 0
Регистрация: 05.08.2012
Сообщений: 83
12.08.2012, 14:54  [ТС] 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 тактов. плин.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.08.2012, 14:54
Помогаю со студенческими работами здесь

Как замерять размер вентилятора?
Зашумел кулер корпуса, разобрал все, какие стоят, продул смазал, два некуда мазать-нет дырдочки....

Как правильно замерять температуру комплектующих
Температуру нужно замерять под нагрузкой, толку от замеров в простое не много. Чем нагружать?...

Как установить модуль rdtsc?
Здравствуйте! Решил найти пример использования модуля Threading. Нашёл пример. Собственно, вот...

Как измерить время выполнения программы с использованием RDTSC
Мне нужно используя RDTSC (как я понял, это ассемблерной вставкой делать нужно) посчитать время...

Как в проекте C# Any CPU (или x64) импортировать функции из нативной DLL Win32?
Написал простейшую DLL в VC++ Express 2008 на основе &quot;Проект Win32&quot;. DLL получилась x86. Как...

Как правильно вычислить значение нагрузки CPU с удаленного сервера windows или linux?
Здравствуйте. Возникло желание написать приложение на java, которое может снимать статистику CPU...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru