Я написал тест для проверки некоторых конкретных функций.Запуск эталонного теста обычно давал непротиворечивые результаты, но примерно в одном случае из десяти он выполнялся примерно в 3 раза быстрее в каждом контрольном тесте.
Я задавался вопросом, было ли какое-то предсказание ветвления или локальность кэшаНа этот раз я запустил perf
, вот так:
sudo perf stat -B -e cache-references,cache-misses,task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,branches,branch-misses ./my_benchmark
Теперь результаты перевернуты : примерно в девяти случаях из десяти он работает быстрее, и в этом случаеperf stat
вывод выглядит так:
Performance counter stats for './my_benchmark':
336,011 cache-references # 75.756 M/sec (41.40%)
74,722 cache-misses # 22.238 % of all cache refs
4.435442 task-clock (msec) # 0.964 CPUs utilized
0 context-switches # 0.000 K/sec
0 cpu-migrations # 0.000 K/sec
572 page-faults # 0.129 M/sec
13,745,945 cycles # 3.099 GHz
16,521,518 instructions # 1.20 insn per cycle
4,453,340 branches # 1004.035 M/sec
91,336 branch-misses # 2.05% of all branches (58.60%)
0.004603313 seconds time elapsed
И примерно в одном из десяти испытаний он работает в 3 раза медленнее, показывая результаты примерно так:
Performance counter stats for './my_benchmark':
348,441 cache-references # 22.569 M/sec (74.14%)
112,153 cache-misses # 32.187 % of all cache refs (74.14%)
15.439061 task-clock (msec) # 0.965 CPUs utilized
0 context-switches # 0.000 K/sec
0 cpu-migrations # 0.000 K/sec
572 page-faults # 0.037 M/sec
13,717,144 cycles # 0.888 GHz (62.52%)
16,951,632 instructions # 1.24 insn per cycle (88.40%)
4,463,213 branches # 289.086 M/sec
70,185 branch-misses # 1.57% of all branches (89.20%)
0.015999175 seconds time elapsed
Я заметил, что задача всегдакажется, завершается примерно за то же число циклов , но частоты разные - в «быстром» случае он показывает что-то вроде 3GHz, тогда как в медленном случае он показывает что-то вроде 900 МГц.Я не знаю точно, что означает эта статистика, поэтому я не знаю, является ли это просто тавтологическим следствием такого же количества циклов и более продолжительного времени выполнения, или же это означает, что часы процессора на самом деле работают с другой скоростью.
Я заметил, что в обоих случаях он говорит: «переключение контекста: 0» и «миграция процессора: 0», поэтому не похоже, что замедление происходит из-за прерванного теста.
Что здесь происходит, и могу ли я написать (или запустить?) Свою программу таким образом, чтобы я всегда получал более высокую производительность?