пятница, 27 марта 2020 г.

Измерение времени выполнения кода с помощью rdtsc, rdtscp

1. rdtsc

Начиная с gcc 4.5 функция __rdtsc() определена под MSVC и под GCC, надо только в коде включить разные хэдэры:

#if defined(_WIN32) 
#include <intrin.h>
#endif

#if !defined(_WIN32) 
#include <x86intrin.h> 
#endif

До gcc 4.5 можно запилить следующее определение функции rdtsc для windows и linux:

//! windows
#if defined(_WIN32)
#include <intrin.h>uint64_t rdtsc(){ 
  return __rdtsc();
}

#endif

//! linux
#if !
defined(_WIN32) 

uint64_t ull rdtsc() {
  unsigned int lo, hi;
  asm volatile ( "rdtsc" : "=a" (lo), "=d" (hi) );
  return ((uint64_t)hi << 32) | lo;
}

#endif

Ссылки:
1) https://ru.wikipedia.org/wiki/Rdtsc
2) Максимально точное измерение кода https://habr.com/ru/post/147852/
3) Измерение кода с наносекундной точностью https://habr.com/ru/post/425237/
4) Оптимизация длинной арифметики на C++ https://habr.com/ru/post/135590/
5) (!) https://stackoverflow.com/questions/13772567/how-to-get-the-cpu-cycle-count-in-x86-64-from-c
6) https://stackoverflow.com/questions/9887839/how-to-count-clock-cycles-with-rdtsc-in-gcc-x86
7) https://stackoverflow.com/questions/19941588/negative-clock-cycle-measurements-with-back-to-back-rdtsc
8) (!) https://stackoverflow.com/questions/51818655/clflush-to-invalidate-cache-line-via-c-function/
9) http://www.mkurnosov.net/uploads/Main/mkurnosov-rdtsc-2014.pdf
10) Примеры https://ru.wikibooks.org/

asm rdtsc:
1) https://c9x.me/x86/html/file_module_x86_id_278.html
2) https://www.felixcloutier.com/x86/rdtsc
3) http://www.club155.ru/x86cmd/RDTSC

2. rdtsp:

Ссылки:
1) https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf
2) https://stackoverflow.com/questions/12631856/difference-between-rdtscp-rdtsc-memory-and-cpuid-rdtsc

asm rdtsp:
1) https://www.felixcloutier.com/x86/rdtscp

3. out-of-order code execution:
1) Внеочередное исполнение (английская статья)
2) Lecture 14 - Out-of-Order Execution - Carnegie Mellon - Computer Architecture 2013 - Onur Mutlu https://www.youtube.com/watch?v=LU2W-YtyeEo
3) Out of Order Load Store Execution - Georgia Tech - HPCA: Part 3
https://www.youtube.com/watch?v=WC5Bo9UdI2w

4. lfence

Ссылки:
1) Барьер памяти
2) https://stackoverflow.com/questions/7346893/out-of-order-execution-and-memory-fences

asm lfence:
1) https://www.felixcloutier.com/x86/lfence
2) https://c9x.me/x86/html/file_module_x86_id_155.html

5. cpuid

Ссылки:
1) https://ru.wikipedia.org/wiki/CPUID
2) https://stackoverflow.com/questions/32662518/cpuid-rdtsc-and-out-of-order-execution

6. tsc frequency

Links:
1) https://stackoverflow.com/questions/51919219/determine-tsc-frequency-on-linux

7. CPUID features relevant to the TSC

Links:
1) https://stackoverflow.com/questions/13772567/how-to-get-the-cpu-cycle-count-in-x86-64-from-c
2) https://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean

8. calc tsc freq by call usleep, nanosleep, delay in asm and rdtscp

Links:
1) https://stackoverflow.com/questions/10921210/cpu-tsc-fetch-operation-especially-in-multicore-multi-processor-environment
2) https://stackoverflow.com/questions/3830883/cpu-cycle-count-based-profiling-in-c-c-linux-x86-64
3) https://stackoverflow.com/questions/2814569/calculating-cpu-frequency-in-c-with-rdtsc-always-returns-0
4) https://stackoverflow.com/questions/12777254/time-delay-in-c-usleep/12777296
5) https://linux.die.net/man/3/usleep
6) https://stackoverflow.com/questions/7684359/how-to-use-nanosleep-in-c-what-are-tim-tv-sec-and-tim-tv-nsec
7) https://man7.org/linux/man-pages/man2/nanosleep.2.html
8) https://stackoverflow.com/questions/15201955/how-to-set-1-second-time-delay-at-assembly-language-8086
9) https://stackoverflow.com/questions/19580282/nasm-assembly-linux-timer-or-sleep/19580595#19580595


9. getting cpu frequency (rate) to produce nanoseconds from ticks

9.1. Можно получить текущую частоту процессорных ядер по отдельности при помощи следующей команды:

cat /proc/cpuinfo | grep "MHz"

Или так (вместо * можно написать номер ядра):

sudo cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq

Или так без sudo:

cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq

9.2. Общую частоту можно получить так:

lscpu | grep MHz

Или так:

sudo dmidecode -t processor | grep Speed

Ссылки:
1) https://stackoverflow.com/questions/35123379/getting-tsc-rate-in-x86-kernel
2) https://www.systutorials.com/measuring-time-accurately-in-programs/
3) https://en.wikipedia.org/wiki/Time_Stamp_Counter
4) (!) https://askubuntu.com/questions/218567/any-way-to-check-the-clock-speed-of-my-processor
5) https://unix.stackexchange.com/questions/264632/what-is-the-correct-way-to-view-your-cpu-speed-on-linux
6) http://btorpey.github.io/blog/2014/02/18/clock-sources-in-linux/
7) not using rdtsc https://stackoverflow.com/questions/5248915/execution-time-of-c-program
8) (!) https://stackoverflow.com/questions/42189976/calculate-system-time-using-rdtsc
9) https://ru.wikipedia.org/wiki/Skylake

Cash misses:


Некоторая статистика по микропроцессорам, частоте и предельным таймерам:

1) SoC BBB - микроконтроллер TI AM3358 - микроархитектура ARM Cortex-A8 - частота 1 ГГц = 10^9 Гц - регистры 32 бит. Предельный идеальный таймер  - с размерностью 32 бит и точностью 1 / 10^9 = 1 наносекунда.

2) SoC Raspberry Pi 3B - микроконтроллер Broadcom BCM 2837 - микроархитектура ARM Cortex-A53 - частота 1.2 ГГц - регистры 64 бит. Предельный идеальный таймер  - с размерностью 64 бит и точностью 1 / 10^9 = 1 наносекунда.

3) SoC STM32 "BluePill" - микроконтроллер STM32f103 - микроархитектура ARM Cortex M3  - частота 32 МГц - регистры 32 бит. Предельный идеальный таймер  - с размерностью 32 бит и точностью 1 / 10^6 = 1 микросекунда.

4) SoC STM32 f429 Discovery - микроконтроллер STM32f429 - микроархитектура ARM Cortex M4  - частота 180 МГц - регистры 32 бит. Предельный идеальный таймер  - с размерностью 32 бит и точностью 1 / 10^6 = 1 микросекунда.

5) Микропроцессор Intel Core i5 520m - микроархитектура Westmere - частота 2.4 ГГц - регистры 64 бит. Предельный идеальный таймер  - с размерностью 64 бит и точностью 1 / 10^9 = 1 наносекунда.

High Resolution Timer In Linux (links):
1) https://elinux.org/High_Resolution_Timers
2) https://www.kernel.org/doc/Documentation/timers/hrtimers.txt
3) https://stackoverflow.com/questions/6749621/how-to-create-a-high-resolution-timer-in-linux-to-measure-program-performance
4) https://forum.qt.io/topic/31369/high-resolution-timer
5) https://stackoverflow.com/questions/15730765/qt-high-resolution-timer

6) Методы измерения кода помимо rdtsc https://habr.com/ru/post/282301/
7) Оптимизация кода для эльбрусов https://habr.com/ru/company/smartengines/blog/317672/

Вики разных единиц измерения скорости вычисления операций процами:
1) https://en.wikipedia.org/wiki/Instructions_per_second
2) https://en.wikipedia.org/wiki/Instructions_per_cycle
3) https://en.wikipedia.org/wiki/Cycle_per_second
4) https://en.wikipedia.org/wiki/Cycles_per_instruction
5) https://en.wikipedia.org/wiki/Normalized_frequency_(unit)
6) https://en.wikipedia.org/wiki/Heinrich_Hertz

Комментариев нет:

Отправить комментарий