| 
    
     | 
    Bog BOS: oprofile - исследование особенностей вычислительной производительности с использованием аппаратных счётчиков событий
       
     | 
  
Последнее изменение файла: 2022.03.28
Скопировано с www.bog.pp.ru: 2025.11.04
Bog BOS: oprofile - исследование особенностей вычислительной производительности с использованием аппаратных счётчиков событий
oprofile - исследование особенностей вычислительной производительности на уровне системы
с использованием встроенных в ЦП счётчиков событий: такты ядра, такты шины, обращений к шине, промахи кеша и т.п.
(количество счётчиков, поддерживаемые типы событий и маски событий зависят от архитектуры и модели ЦП).
Можно подсчитывать события, происходящие в режиме ядра, в режиме пользователя или обоих режимах.
При достижении заданного числа событий проиcходит прерывание (NMI, non-maskable interrupts), обработчик прерывания
записывает сообщение о событии (счётчик адреса и номер процесса) в буфер ядра,
сервис oprofiled переносит накопленные данные из буфера ядра в файл.
Сохранённый счётчик адреса и стек вызовов позволяет привязывать события к программам (модулям ядра), операторам ЯВУ и командам.
Позволяет определить "узкое горло", включая подсистемы ядра (модули и обработчики прерываний).
В качестве прообраза использовалась система DCPI (DEC Continuous Profiling Infrastructure).
Не оказывает воздействия на исполняемые программмы ни в поведении, ни в производительности (счётчики обновляются аппаратно).
Пакет oprofile (oprofile-gui, oprofile-jit, oprofile-devel) версии 0.9.4 в RHEL5.4 
(для Nehalem (i7, Xeon 55xx) требуется 0.9.5).
Для IBS (Instruction-Based Sampling) для AMD K10 требуется ядро 2.6.28.
Используется модуль ядра oprofile, демон oprofiled, утилита управления opcontrol 
и утилиты генерации отчётов opreport (возможна фильтрация по программам) и opannotate (с точностью до строки ЯВУ или команды).
Перед запуском мониторинга блокируется NMI watchdog, для разблокировки требуется выгрузить модуль ядра.
Внеочередное исполнение инструкций в современных ЦП не позволяет привязать данные с точностью до команды.
Записывается не каждое событие, а одно из N событий (каждый счётчик имеет ограничение на N снизу).
При уменьшении N увеличивается побочная нагрузка на систему вплоть до зависания
(при уменьшении N с 30000 до 3000 время расчёта увеличилось вдвое (на 20%), доля потерь отсчётов в 1.5 раза (в 8 раз);
при увеличении - уменьшается точность (потери отсчётов из-за переполнения буфера пропали при увеличении до 50000
на AMD K10 с частотой 2800MHz при нагрузке на все 24 ядра).
Заброшена в пользу perf.
Модуль ядра oprofile имеет параметры: p4force, timer (использовать только прерывания от таймера).
По умолчанию, счётчик 0 отслеживает событие CPU_CLK_UNHALTED (для Core2/K10).
Для управления используется файловая система в каталоге /dev/oprofile/, в котором можно посмотреть текущее состояние,
задать параметры мониторинга и взять результаты (почему он в /dev, а не в /proc или /sys?).
Максимальное количество одновременно используемых счётчиков определяется моделью ЦП, нумеруются с 0,
каждый счётчик имеет подкаталог в /dev/oprofile/ (отсюда можно определить их число):
- /dev/oprofile/cpu_type - тип ЦП с точки зрения модуля
 
- /dev/oprofile/cpu_buffer_size - размер буфера ядра
 
- /dev/oprofile/buffer_size - размер буфера 
 - /dev/oprofile/stats/ - статистика сбора информации (количество потерянных отсчётов)
 
- /dev/oprofile/0/enabled - счётчик включён
 
- /dev/oprofile/0/count - количество событий между прерываниями
 
- /dev/oprofile/0/event - тип событий
 
- /dev/oprofile/0/unit_mask - маска
 
- /dev/oprofile/0/kernel - учитывать события в режиме ядра
 
- /dev/oprofile/0/user - учитывать события в режиме пользователя
 
"ophelp -r" выдаёт тип ЦП. 
ophelp с указанием имени счётчика выдаёт его номер.
ophelp без параметров выдаёт список допустимых счётчиков и масок, например,
для Intel Xeon 55xx (Nehalem, i7; 5 счётчиков, 31 bit? не получается задать больше 1 счётчика):
- счётчики тактов
  
  - CPU_CLK_UNHALTED - такты, в которых ЦП не был в состоянии останова 
    (по умолчанию, маска 0x00 - циклы ядра; 0x01 - циклы шины, 0x02 - при остановленных остальных ядрах)
 
  
 
- счётчики инструкций, микроопераций, прерываний
  
  - INST_RETIRED_ANY_P - количество выполненных инструкций
 
  - SEGMENT_REG_LOADS
 
  - FLOPS - микрокоманд плавающей арифметики
 
  - MUL - число умножений
 
  - DIV - число делений
 
  - EIST_TRANS_ALL - количество переходов Intel Enhanced SpeedStep Technology
 
  - THERMAL_TRIP - количество температурных переходов
 
  - RS_UOPS_DISPATCHED - количество микрокоманд, запланированных к выполнению
 
  - RS_UOPS_DISPATCHED_NONE - количество пустых микрокоманд, запланированных к выполнению
 
  - MACRO_INSTS - количество декодированных команд (по умолчанию, маска 0x9; 1 - команд, 8 - команд CISC)
 
  - SIMD_UOPS_EXEC - количество выполненных SIMD команд
 
  - SIMD_SAT_UOP_EXEC - количество выполненных "насыщающих" (saturating?) SIMD команд
 
  - SIMD_UOP_TYPE_EXEC - количество пакованных SIMD команд (по умолчанию, маска 0x3f;
      1 - умножений, 2 - сдвигов, 4 - паковок, 8 - распаковок, 0x10 - логических, 0x20 - арифметических)
 
  - SIMD_INST_RETIRED - команд SSE/SSE2 (по умолчанию, маска 0x1f; 1 - SSE packed-single, 2 - SSE scalar-single,
      4 - SSE2 packed-double, 8 - SSE2 scalar-double, 0x10 - SSE2 vector integer)
 
  - SIMD_COMP_INST_RETIRED - команд SSE/SSE2 (по умолчанию, маска 0xf; 1 - SSE packed-single, 2 - SSE scalar-single,
      4 - SSE2 packed-double, 8 - SSE2 scalar-double)
 
  - SIMD_INSTR_RET - количество команд SIMD
 
  - SIMD_SAT_INSTR_RET - количество "насыщающих" (saturating?) SIMD команд
 
  - INST_RETIRED - количество выполненных инструкций (по умолчанию, маска 0x00 - любых;
      0x01 - команд загрузки, 0x02 - команд записи,
      0x04 - других)
 
  - X87_OPS_RETIRED - количество команд с плавающей точкой
 
  - UOPS_RETIRED - количество микрокоманд (по умолчанию, маска 0xf;
      1 - слитых "загрузка и операция" или "загрузка и косвенный переход";
      2 - слитых "запись адреса и адреса"; 
      4 - пара команд слитых в одну микрокоманду;
      8 - неслитых микрокоманд)
 
  - FP_MMX_TRANS - преобразований между FP и MMX (по умолчанию, маска 3; 1 - из FP в MMX, 2 - из MMX в FP)
 
  - MMX_ASSIST - количество команд EMMS
 
  - HW_INT_RCV - количество аппаратных прерываний
 
  - CYCLES_INT_MASKED - количество циклов с замаскированными прерываниями (по умолчанию, маска 2;
      1 - с замаскированными прерываниями; 2 - с замаскированными прерываниями при наличии прерываний0
 
  - BR_INST_DECODED - декодированных команд перехода
 
  - BR_BOGUS - количество фиктивных переходов
 
  - BR_INST_EXEC - выполненных команд перехода
 
  - BR_MISSP_EXEC - неправильно предсказанных выполненных команд перехода
 
  - BR_BAC_MISSP_EXEC - неправильно предсказанных на входе (at Front End, BAC) выполненных команд перехода
 
  - BR_CND_EXEC и BR_CND_MISSP_EXEC - условных переходов и неправильно предсказанных условных переходов
 
  - BR_IND_EXEC и BR_IND_MISSP_EXEC - косвенных переходов и неправильно предсказанных косвенных переходов
 
  - BR_RET_EXEC, BR_RET_MISSP_EXEC, BR_RET_BAC_MISSP_EXEC - команд возврата, неправильно предсканных, непраильно
      предсказанных на входе
 
  - BR_CALL_EXEC, BR_CALL_MISSP_EXEC - вызовов функций и неправильно предсказанных вызовов функций
 
  - BR_IND_CALL_EXEC - косвенных вызовов
 
  - BR_TKN_BUBBLE_1, BR_TKN_BUBBLE_2 - предсказанных переходов
 
  - BR_INST_RETIRED - команд перехода (по умолчанию, маска 0xa - неправильно предсказанных)
 
  - BR_MISS_PRED_RETIRED - неправильно предсказанных команд перехода
 
  
 
- эффективность кеширования
  
  - L1D_CACHE_LD - количество кешированных чтений данных (по умолчанию, маска 0xf - MESI)
 
  - L1D_CACHE_ST - количество кешированных записей данных (по умолчанию, маска 0xf - MESI)
 
  - L1D_CACHE_LOCK - количество кешированных чтений данных с блокировкой (по умолчанию, маска 0xf - MESI)
 
  - L1D_CACHE_LOCK_DURATION - длительность кешированных операций с блокировкой
 
  - L1D_ALL_REF - обращений к L1D
 
  - L1D_ALL_CACHE_REF - кешированных чтений и записей
 
  - L1D_REPL - количество строк, резервированных в L1D
 
  - L1D_M_REPL - количество изменённых строк, резервированных в L1D
 
  - L1D_M_EVICT - количество изменённых строк, изгнанных из L1D
 
  - L1D_PEND_MISS - количество промахов в L1D в ожидании
 
  - L1D_SPLIT - количество разбитых строк L1D (по умолчанию, маска 0x1 - загрузок; 2 - сохранений)
 
  - L1I_READS - количество загрузок инструкций из L1I
 
  - L1I_MISSES - количество загрузок инструкций из L1I с промахом
 
  - L1D_PREFETCH - количество команд предзагрузки L1D
 
  - L2_RQSTS - запросов управления L2 (по умолчанию, маска 0x7f - от этого ядра)
 
  - LLC_MISSES - промахов L2 от этого ядра
 
  - LLC_REFS - требований к L2
 
  - L2_ADS - циклов, в которых шина адреса L2 занята (по умолчанию, маска 0x40 - это ядро)
 
  - L2_DBUS_BUSY_RD - циклов, в которых L2 передат данные в ядро (по умолчанию, маска 0x40 - это ядро)
 
  - L2_LINES_IN - количество строк, резервированных в L2 (по умолчанию, маска 0x70;
      маска 0xc0 - все ядра, 0x40 - это ядро,
      0x30 - любые предзагрузки, 0x10 - аппаратные предзагрузки, 0x00 - предзагрузки, кроме аппаратных)
 
  - L2_M_LINES_IN - количество изменённых строк, резервированных в L2 (по умолчанию, маска 0x40 - это ядро)
 
  - L2_LINES_OUT - количество строк, явно выведенных из L2 (по умолчанию, маска 0x70 - это ядро, все prefetch)
 
  - L2_M_LINES_OUT - количество изменённых строк, явно выведенных из L2 
      (по умолчанию, маска 0x70 - это ядро, все prefetch)
 
  - L2_IFETCH - количество загрузок команд из L2 (по умолчанию, маска 0x4f - это ядро)
 
  - L2_LD - число загрузок в L2 (по умолчанию, маска 0x7f - это ядро)
 
  - L2_ST - число записей из L2 (по умолчанию, маска 0x4f - это ядро)
 
  - L2_LOCK - число заблокированных обращений L2 (по умолчанию, маска 0x4f - это ядро)
 
  - L2_REJECT_BUSQ - число отвергнутых запросов L2 (по умолчанию, маска 0x7f - это ядро)
 
  - L2_NO_REQ - количество циклов без ожидания L2 (по умолчанию, маска 0x40 - это ядро)
 
  - PREF_RQSTS_UP - количество предзагрузок вперёд
 
  - PREF_RQSTS_DN - количество предзагрузок назад
 
  - EXT_SNOOP - внешних snoop (по умолчанию, маска 0xb - всех для этого агента)
 
  - CMP_SNOOP - snoop L1D другими ядрами (по умолчанию, маска 0x40 - это ядро)
 
  - SSE_PRE_EXEC - количество команд загрузки кеша (по умолчанию, маска 0 - NTA; 1 - T1; 2 - T1 и T2; 
      3 - SSE weakly-ordered stores)
 
  - SSE_PREF_MISS - команды предзагрузки SSE промахнувшиеся мимо всех кешей (по умолчанию, маска 0 - PREFETCHNTA;
      1 - PREFETCHT0; 2 - PREFETCHT1/PREFETCHT2)
 
  
 
- TLB
  
  - DTLB_MISSES - промахов DTLB (по умолчанию, маска 0xf;
      маска 0x01 (ANY) - любых, 0x02 (MISS_LD) - промахов команд загрузки, 
      0x04 (L0_MISS_LD) - промахов L0 DTLB (?) команд загрузки, 0x08 (MISS_ST) - промахов команд записи
 
  - ITLB - промахов ITLB (по умолчанию, маска 0x12; 0x02 - промах малой страницы; 0x10 - промах большой страницы;
      0x40 - сбросов ITLB)
 
  - ITLB_MISS_RETIRED - промахов ITLB
 
  
 
- проблемы
  
  - MISALIGN_MEM_REF - невыровненных адресов памяти
 
  - MACHINE_NUKES_SMC - количество сбросов конвейера (по умолчанию, маска 0x5; 1 - самомодифицирующийся код;
      4 - конфликт доступа к памяти)
 
  - RAT_STALLS - циклов, блокированных из-за частичного заполнения регистров (по умолчанию, маска 0xf - все виды)
 
  - RESOURCE_STALLS - блокировок из-за проблем с ресурсами (по умолчанию, маска 0xf - все)
 
  - SNOOP_STALL_DRV - Bus stalled for snoops (по умолчанию, маска 0x40 - это ядро)
 
  - INST_QUEUE_FULL - количество циклов, в которых очередь команд переполнена
 
  - IFU_MEM_STALL - количество циклов, в которых конвейер загрузки команд застрял
 
  - ILD_STALL - количество циклов, в которых декодер длины команд застрял
 
  
 
- запросы к памяти, в/в и другим ЦП
  
  - MEM_LOAD_RETIRED - количество загрузок (по умолчанию, маска 0x1; 1 - загрузок мимо L1D,
      2 - загрузок строки кеша мимо L1D, 4 - загрузок мимо L2, 8 - загрузок строки кеша мимо L2,
      0x10 - загрузок мимо DTLB
 
  - LOAD_BLOCK - блокировок загрузки (по умолчанию, маска 0x3e - все)
 
  - STORE_BLOCK - блокировок записи (по умолчанию, маска 0xb - все)
 
  - BUS_REQ_OUTSTANDING - длительность кешируемых запросов чтения шины в очереди (по умолчанию, маска 0x40 - это ядро)
 
  - BUS_BNR_DRV - количество сигналов Bus Not Ready
 
  - BUS_DRDY_CLOCKS - количество циклов шины, когда по ней пересылаются данные
 
  - BUS_LOCK_CLOCKS - количество сигналов LOCK на шине (по умолчанию, маска 0x40 - это ядро)
 
  - BUS_DATA_RCV - количество циклов шины, когда процессор получает данные (по умолчанию, маска 0x40 - это ядро)
 
  - BUS_TRAN_BRD - количество уплотнённых (burst) транзакций чтения шины (по умолчанию, маска 0x40 - это ядро)
 
  - BUS_TRAN_RFO (read for ownership), BUS_TRAN_WB (writeback), BUS_TRAN_IFETCH (загрузка инструкций),
      BUS_TRAN_INVAL (invalidate), BUS_TRAN_PWR (partial write), BUS_TRANS_P (partial), BUS_TRANS_IO,
      BUS_TRANS_DEF (completed defer), BUS_TRAN_BURST (completed burst), BUS_TRAN_MEM (completed memory),
      BUS_TRAN_ANY (любых завершённых) - количество соответствующих транзакций шины (по умолчанию, маска 0x40 - это ядро)
 
  - BUS_HIT_DRV - количество сигналов HIT на шине
 
  - BUS_HITM_DRV - количество сигналов HITM на шине
 
  - BUSQ_EMPTY - очередь шины пуста (по умолчанию, маска 0x40 - это ядро)
 
  - BUS_IO_WAIT - запросы в/в ждут в очереди шины
 
  
 
ophelp для AMD K10 (все счётчики универсальные; 
4 счётчика по 40 bit? не получается задать более 3):
- счётчики тактов
  
  - CPU_CLK_UNHALTED (единственный счётчик с одинаковым именем для AMD и Intel)
 
  
 
- счётчики инструкций, микроопераций, прерываний
  
  - RETIRED_INSTRUCTIONS (не перепутайте с INST_RETIRED для Intel ;)
 
  - DISPATCHED_FPU_OPS (по умолчанию, маска 0x3f - все команды)
 
  - RETIRED_SSE_OPS (по умолчанию, маска 0x7f - все команды)
 
  - RETIRED_MOVE_OPS (по умолчанию, маска 0xf - все команды)
 
  - RETIRED_SERIALIZING_OPS (по умолчанию, маска 0xf - все команды)
 
  - RETIRED_UOPS
 
  - RETIRED_BRANCH_INSTRUCTIONS
 
  - RETIRED_MISPREDICTED_BRANCH_INSTRUCTIONS
 
  - RETIRED_TAKEN_BRANCH_INSTRUCTIONS
 
  - RETIRED_TAKEN_BRANCH_INSTRUCTIONS_MISPREDICTED
 
  - RETIRED_FAR_CONTROL_TRANSFERS
 
  - RETIRED_BRANCH_RESYNCS
 
  - RETIRED_NEAR_RETURNS
 
  - RETIRED_NEAR_RETURNS_MISPREDICTED
 
  - RETIRED_INDIRECT_BRANCHES_MISPREDICTED
 
  - RETIRED_MMX_FP_INSTRUCTIONS (по умолчанию, маска 0x7; 1 - инструкции x87, 2 - MMX и 3DNow, 4 - SSE)
 
  - RETIRED_FASTPATH_DOUBLE_OP_INSTRUCTIONS (по умолчанию, маска 0x7)
 
  - INTERRUPTS_TAKEN
 
  - INTERRUPTS_MASKED_CYCLES (циклы с маскированными прерываниями)
 
  - INTERRUPTS_MASKED_CYCLES_WITH_INTERRUPT_PENDING
 
  - DR0_BREAKPOINTS, DR1_BREAKPOINTS, DR2_BREAKPOINTS, DR3_BREAKPOINTS
 
  - SIZED_COMMANDS(по умолчанию, маска 0x3f)
 
  
 
- эффективность кеширования
  
  - LS_BUFFER_2_FULL_CYCLES
 
  - DATA_CACHE_ACCESSES
 
  - DATA_CACHE_MISSES
 
  - DATA_CACHE_REFILLS_FROM_L2_OR_NORTHBRIDGE (по умолчанию, маска 0x1e - All cache states except refill from northbridge;
    1 - Refill from northbridge; 2 - Shared-state line from L2, 4 - Exclusive-state line from L2,
    8 - Owner-state line from L2, 0x10 - Modified-state line from L2)
  
 
  - DATA_CACHE_REFILLS_FROM_NORTHBRIDGE (по умолчанию, маска 0x1f - All cache states)
 
  - DATA_CACHE_LINES_EVICTED (по умолчанию, маска 0x1f)
 
  - INEFFECTIVE_SW_PREFETCHES (по умолчанию, маска 0x9)
 
  - DATA_PREFETCHES (аппаратные; по умолчанию, маска 0x3)
 
  - REQUESTS_TO_L2 (по умолчанию, маска 0x3f)
 
  - L2_CACHE_MISS (по умолчанию, маска 0xf)
 
  - L2_CACHE_FILL_WRITEBACK (по умолчанию, маска 0x3)
 
  - INSTRUCTION_CACHE_FETCHES
 
  - INSTRUCTION_CACHE_MISSES
 
  - INSTRUCTION_CACHE_REFILLS_FROM_L2
 
  - INSTRUCTION_CACHE_REFILLS_FROM_SYSTEM
 
  - INSTRUCTION_CACHE_VICTIMS
 
  - INSTRUCTION_CACHE_INVALIDATED (по умолчанию, маска 0xf)
 
  - CACHE_BLOCK_COMMANDS (по умолчанию, маска 0x3d)
 
  - READ_REQUEST_L3_CACHE (по умолчанию, маска 0xf7)
 
  - L3_CACHE_MISSES (по умолчанию, маска 0xf7)
 
  - L3_FILLS_CAUSED_BY_L2_EVICTIONS (по умолчанию, маска 0xff)
 
  - L3_EVICTIONS (по умолчанию, маска 0xf)
 
  
 
- TLB
  
  - L1_DTLB_MISS_AND_L2_DTLB_HIT
 
  - L1_DTLB_AND_L2_DTLB_MISS
 
  - L1_DTLB_HIT
 
  - L1_ITLB_MISS_AND_L2_ITLB_HIT
 
  - L1_ITLB_MISS_AND_L2_ITLB_MISS
 
  - GLOBAL_TLB_FLUSHES
 
  - ITLB_RELOADS
 
  - ITLB_RELOADS_ABORTED
 
  
 
- проблемы
  
  - PIPELINE_RESTART_DUE_TO_SELF_MODIFYING_CODE
 
  - PIPELINE_RESTART_DUE_TO_PROBE_HIT
 
  - LOCKED_OPS (маска 1 - locked instructions, 2 - Cycles in speculative phase, 
    4 - Cycles in non-speculative phase (including cache miss penalty), 8 - Cache miss penalty in cycles)
  
 
  - MISALIGNED_ACCESSES
 
  - 1_BIT_ECC_ERRORS (по умолчанию, маска 0xf)
 
  - PIPELINE_RESTART_DUE_TO_INSTRUCTION_STREAM_PROBE
 
  - INSTRUCTION_FETCH_STALL
 
  - RETURN_STACK_HITS
 
  - RETURN_STACK_OVERFLOWS
 
  - DECODER_EMPTY
 
  - DISPATCH_STALLS
 
  - DISPATCH_STALL_FOR_BRANCH_ABORT
 
  - DISPATCH_STALL_FOR_SERIALIZATION
 
  - DISPATCH_STALL_FOR_SEGMENT_LOAD
 
  - DISPATCH_STALL_FOR_REORDER_BUFFER_FULL
 
  - DISPATCH_STALL_FOR_RESERVATION_STATION_FULL
 
  - DISPATCH_STALL_FOR_FPU_FULL
 
  - DISPATCH_STALL_FOR_LS_FULL
 
  - DISPATCH_STALL_WAITING_FOR_ALL_QUIET
 
  - DISPATCH_STALL_FOR_FAR_TRANSFER_OR_RESYNC
 
  - FPU_EXCEPTIONS (по умолчанию, маска 0xf)
 
  - THERMAL_STATUS (по умолчанию, маска 0x7c)
 
  
 
- запросы к памяти, в/в и другим ЦП
  
  - MEMORY_REQUESTS (по умолчанию, маска 0x83)
 
  - NORTHBRIDGE_READ_RESPONSES (по умолчанию, маска 0x17)
 
  - OCTWORD_WRITE_TRANSFERS
 
  - DRAM_ACCESSES (по умолчанию, маска 0xff; 0x7 - DCT0, 0x38 - DCT1, 0x40 - запись, 0x80 - чтение)
 
  - MEMORY_CONTROLLER_PAGE_TABLE_OVERFLOWS
 
  - MEMORY_CONTROLLER_SLOT_MISSED
 
  - MEMORY_CONTROLLER_TURNAROUNDS
 
  - MEMORY_CONTROLLER_BYPASS_COUNTER_SATURATION
 
  - CPU_IO_REQUESTS_TO_MEMORY_IO (по умолчанию, маска 0xa2 - Local I/O to Local Memory;
      0xa8 - Local CPU to Local Memory; 0x98 - Local CPU to Remote Memory; ...)
 
  - PROBE_RESPONSES_AND_UPSTREAM_REQUESTS (по умолчанию, маска 0xff)
 
  - GART_EVENTS (по умолчанию, маска 0xff)
 
  - MEMORY_CONTROLLER_REQUESTS  (по умолчанию, маска 0x78 - чтение или запись 32 или 64 байт)
 
  - CPU_DRAM_REQUEST_TO_NODE (зпрос к памяти определённого узла; по умолчанию, маска 0xff;
      1 - к узлу 0; 2 - к узлу 1, 4 - к узлу 2, 8 - к узлу 3)
 
  - IO_DRAM_REQUEST_TO_NODE
 
  - CPU_READ_COMMAND_LATENCY_NODE_0_3 (задержка между локальным и удалённым узлом; по умолчанию, маска 0xff)
 
  - CPU_READ_COMMAND_REQUEST_NODE_0_3 (число запросов, задержка которых подсчитывается; по умолчанию, маска 0xff)
 
  - CPU_READ_COMMAND_LATENCY_NODE_4_7 (задержка между локальным и удалённым узлом; по умолчанию, маска 0xff)
 
  - CPU_READ_COMMAND_REQUEST_NODE_4_7 (число запросов, задержка которых подсчитывается; по умолчанию, маска 0xff)
 
  - CPU_COMMAND_LATENCY_TARGET
 
  - CPU_REQUEST_TARGET
 
  - HYPERTRANSPORT_LINK0_TRANSMIT_BANDWIDTH (по умолчанию, маска 0xbf)
 
  - HYPERTRANSPORT_LINK1_TRANSMIT_BANDWIDTH (по умолчанию, маска 0xbf)
 
  - HYPERTRANSPORT_LINK2_TRANSMIT_BANDWIDTH (по умолчанию, маска 0xbf)
 
  - HYPERTRANSPORT_LINK3_TRANSMIT_BANDWIDTH (по умолчанию, маска 0xbf)
 
  
 
Демон oprofiled запускается и останавливается утилитой opcontrol,
периодически считывает собранные данные из аппаратных счётчиков
(/dev/oprofile/) и сохраняет их в файлах (/var/lib/oprofile/samples/current).
Журнал - /var/lib/oprofile/samples/oprofile.log (обратить внимание на количество потерь отсчётов в связи
с переполнением буфера).
  
    opcontrol - управление демоном  | 
  
Утилита opcontrol позволяет управлять сбором данных. Требуются права суперпользователя.
Загрузка модуля и прочая инициализация:
opcontrol --init
Настройка демона:
opcontrol --setup ключи-настройки
- --vmlinux=/usr/lib/debug/lib/modules/2.6.18-164.15.1.el5/vmlinux (для профилирования ядра
    требуется несжатое ядро, которое можно взять из пакетов 
    kernel-debuginfo и kernel-debuginfo-common (файл /usr/lib/debug/lib/modules/версия-ядра/vmlinux) -
    для CentOS с http://debuginfo.centos.org/5/x86_64/)
 
- --no-vmlinux (профилирование ядра не требуется)
 
- --buffer-size=отсчётов (размер буфера ядра)
 
- --buffer-watershed=отсчётов (рекомендуется от 0.25 до 0.5 размера буфера)
 
- --cpu-buffer-size=отсчётов (буферизация отсчётов для каждого ЦП, увеличение уменьшает потери отсчётов)
 )
- --event={описание-регистрируемого-события|default} (чтобы задействовать несколько счётчиков необходимо описать
    несколько событий в одной строке; после изменений необходимо перезапустить сервис oprofiled;
    формат описания - имя-счётчика:число-событий:маска:считать-в-ядре:считать-в-пространстве-пользователя;
    не могу поставить более одного счётчика для Xeon 55xx в RHEL 5.4
    ("ophelp --check-events" проходит; 
    пересборка пользовательской части 0.9.5 не помогла - модуль ядра возвращает i386/core_2;
    в /dev/oprofile только 1 счётчик)
 
- --separate=тип-разделения-отсчётов (список через запятую; рекомендуется lib)
  
  - none (по умолчанию, все отсчёты, для которых счётчик адреса указывает на определённую программу, записываются в один
      файл для каждой программы)
 
  - lib (отсчёты, попавшие в динамическую библиотеку, распределяются по приложениям)
 
  - kernel (отсчёты, попавшие в ядро и модули ядра, распределяются по приложениям; подразумевает lib;
      асинхронные события (обработка прерываний) приписывается текущему процессу)
 
  - thread (отсчёты распределяются по потокам и процессам; не стоит оставлять надолго; приходится сливать в opreport?)
 
  - cpu (отсчёты распределяются по ЦП; приходится сливать в opreport?)
 
  - all
 
  
 
- --callgraph=глубина (отслеживать дерево вызовов указанной максимальной глубины; 0 - отключить)
 
- --image={абсолютный-путь|all} (список через запятую; профилировать только указанные программы)
 
- --verbose (не советую использовать под нагрузкой)
 
- --kernel-range=начало,конец
 
Запуск демона и сбора статистики:
opcontrol --start
Запуск только демона:
opcontrol --start-daemon
Посмотреть список событий, доступных для наблюдения:
opcontrol --list-events
Посмотреть настройки:
opcontrol --status
Записать накопленную статистику (в /var/lib/oprofile):
opcontrol --dump
Остановить сбор статистики:
opcontrol --stop
Остановить сбор статистики и остановить демона:
opcontrol --shutdown
Сохранить данные текущей сессии:
opcontrol --save=имя-сессии
Сброс статистики текущей сессии (сохранённые сессии не теряются):
opcontrol --reset
Остановить демон, выгрузить модуль oprofile и размонтировать oprofilefs:
opcontrol --deinit
Конфигурационный файл, который заполняет opcontrol (т.е. при
следующем запуске параметры повторять не обязательно) - /root/.oprofile/daemonrc:
- SESSION_DIR=/var/lib/oprofile
 
- NR_CHOSEN=0
 
- SEPARATE_LIB=1
 
- SEPARATE_KERNEL=1
 
- SEPARATE_THREAD=0
 
- SEPARATE_CPU=0
 
- VMLINUX=/usr/lib/debug/lib/modules/2.6.18-128.7.1.el5/vmlinux
 
- IMAGE_FILTER=
 
- CPU_BUF_SIZE=0
 
- CALLGRAPH=5
 
- KERNEL_RANGE=ffffffff80000000,ffffffff8026f6af
 
- XENIMAGE=none
 
Запуск демона:
opcontrol --start
oprof_start из пакета oprofile-gui позволяет выбрать счётчики в графическом режиме (QT).
oparchive позволяет архивировать накопленные данные. Архив самодостаточен и может быть
использован на другом компьютере. Ключи:
- --exclude-dependent | -x (не включать данные о связанных с программой библиотеках и модулях ядра)
 
- --image-path | -p пути (список путей поиска для программ и модулей ядра - /lib/modules/2.6.18-164.15.1.el5/kernel/)
 
- --root | -r путь
 
- --output-directory | -o каталог
 
opimport конвертирует накопленные данные для их исследования на
компьютере другой архитектуры.
Интересные комбинации для AMD K10
# сбор данных о среднем времен выполнения инструкции (AMD K10):
opcontrol --setup --event=CPU_CLK_UNHALTED:300000 --event=RETIRED_INSTRUCTIONS:300000 --event=RETIRED_UOPS:300000
# выяснение используемых режимов плавающей арифметики:
opcontrol --setup --event=RETIRED_MMX_FP_INSTRUCTIONS:300000:1 \
                  --event=RETIRED_MMX_FP_INSTRUCTIONS:300000:2 \
                  --event=RETIRED_MMX_FP_INSTRUCTIONS:300000:4
# насколько хорошо кеширование L1D:
opcontrol --setup --event=DATA_CACHE_ACCESSES:300000 --event=DATA_CACHE_MISSES:300000 \
                   --event=DATA_CACHE_REFILLS_FROM_L2_OR_NORTHBRIDGE:300000
# насколько хорошо кеширование L1I и L2:
opcontrol --setup --event=REQUESTS_TO_L2:300000 --event=L2_CACHE_MISS:300000 --event=INSTRUCTION_CACHE_MISSES:300000
# насколько хорошо кеширование L3:
opcontrol --setup --event=READ_REQUEST_L3_CACHE:300000 --event=L3_CACHE_MISSES:300000 --event=L3_EVICTIONS:300000
# возможные проблемы, тормозящие вычисления:
opcontrol --setup --event=PIPELINE_RESTART_DUE_TO_SELF_MODIFYING_CODE:500 \
                  --event=MISALIGNED_ACCESSES:300000 --event=1_BIT_ECC_ERRORS:500
# проблемы декодирования команд и планирования запуска:
opcontrol --setup --event=INSTRUCTION_FETCH_STALL:300000 --event=DECODER_EMPTY:300000 --event=DISPATCH_STALLS:300000
# эффективность работы DTLB:
opcontrol --setup --event=L1_DTLB_HIT:300000 --event=L1_DTLB_MISS_AND_L2_DTLB_HIT:300000 --event=L1_DTLB_AND_L2_DTLB_MISS:300000
# эффективность работы ITLB:
opcontrol --setup --event=L1_ITLB_MISS_AND_L2_ITLB_HIT:300000 --event=L1_ITLB_MISS_AND_L2_ITLB_MISS:300000
# сбросы TLB:
opcontrol --setup --event=GLOBAL_TLB_FLUSHES:500 --event=ITLB_RELOADS:500 --event=ITLB_RELOADS_ABORTED:500
# доступ к памяти:
opcontrol --setup --event=MEMORY_REQUESTS:300000 --event=DRAM_ACCESSES:300000 --event=CPU_IO_REQUESTS_TO_MEMORY_IO:300000:0xa8
# доля команд перехода и ошибочных предсказаний
opcontrol --setup --event=RETIRED_INSTRUCTIONS:300000 \
                  --event=RETIRED_BRANCH_INSTRUCTIONS:300000 --event=RETIRED_MISPREDICTED_BRANCH_INSTRUCTIONS:300000
Интересные комбинации для Core2
- декодер команд ждёт данные: CYCLES_L1I_MEM_STALLED / CPU_CLK_UNHALTED.CORE
 
- промах ITLB: ITLB_MISS_RETIRED / INST_RETIRED.ANY
 
- промах L1I: L1I_MISSES / INST_RETIRED.ANY
 
- промах L2 при загрузке инструкций: L2_IFETCH.SELF.I_STATE / INST_RETIRED.ANY
 
- нагрузка на чтение из памяти: L1D_CACHE_LD.MESI / CPU_CLK_UNHALTED.CORE
 
- запись блокирована предыдущей записью: STORE_BLOCK.ORDER / CPU_CLK_UNHALTED.CORE
 
- чтение в L1D блокировано недостаткой ресурсов: LOAD_BLOCK.L1D / CPU_CLK_UNHALTED.CORE
 
- промахи L1D: L1D_REPL / INST_RETIRED.ANY
 
- промахи L2: L2_LINES_IN.SELF.ANY / INST_RETIRED.ANY
 
  
    opreport - генератор отчётов  | 
  
Утилита opreport считывает собранные в /var/lib/oprofile/samples/ данные, фильтрует, сливает,
анализирует их и выводит в человеколюбивом формате. Не требуются права суперпользователя.
Необходимо задать спецификацию профиля для фильтрации (по умолчанию - пустая спецификация,
т.е. использовать все накопленные данные) и опции вывода:
- --accumulated | -a (нарастающим итогом)
 
- --debug-info | -g (выводить имя исходного файла и номер строки, если есть отладочная информация)
 
- --demangle | -D {none|smart|normal} (приводить имена функций C++ к человеческому виду)
 
- --callgraph | -c (выводить граф вызовов функций, если собрана необходимая информация
 
- --details | -d (выводить не только суммарную информацию для прошраммы/библиотеки/модуля целиком,
    но и детализированную информацию для интервалов адресов)
 
- --exclude-dependent | -x (не включать данные о связанных с программой библиотеках и модулях ядра)
 
- --exclude-symbols | -e список-символов (не включать данные о перечисленных символах, требуется --symbols)
 
- --global-percent | -% (все процентные данные выводить относительно общей суммы)
 
- --image-path | -p пути (список путей поиска для программ и модулей ядра - /lib/modules/2.6.18-164.15.1.el5/kernel/)
 
- --root | -r путь
 
- --include-symbols | -i список-символов (включать данные только о перечисленных символах, требуется --symbols)
 
- --long-filenames | -f (выводить полные пути)
 
- --merge | -m {lib,cpu,tid,tgid,unitmask,all} (слить данные, собранные с ключом --separate; 
    tgid - по задачам, tid - по нитям)
 
- --no-header
 
- --reverse-sort | -r
 
- --session-dir имя-каталога (по умолчанию - /var/lib/oprofile)
 
- --show-address | -w (показать виртуальные адреса; требуется --symbols)
 
- --sort | -s {vma,sample,symbol,debug,image}
 
- --symbols | -l (вывести посимвольную информацию)
 
- --threshold | -t процентов (не выводить малозначимые данные)
 
- --xml | -X (в формате XML; opreport.xsd)
 
Спецификация профиля (фильтр отбора данных) состоит из комбинации следующих параметров через пробел:
- archive:имя-архива (см. утилиту oparchive)
 
- session:список-сессий (по умолчанию - current)
 
- session-exclude:список-сессий
 
- image:список-программ (можно использовать полные имена, относительные имена, шаблоны)
 
- image-exclude:список-программ
 
- lib-image:список-программ
 
- lib-image-exclude:список-программ
 
- event:имя-события
 
- count:количество-отсчётов
 
- unit-mask:маска
 
- cpu:список-ЦП (нумерация с нуля; требуется сбор данных с --separate=cpu)
 
- tgid:список-номеров-процессов (tgid - task group id; требуется сбор данных с --separate=thread)
 
- tid:список-номеров-потоков (требуется сбор данных с --separate=thread)
 
opreport позволяет сравнить 2 профиля (не забывайте пробелы и экранировку от bash):
opreport ключи общая-часть-спецификации { отличия-первого-профиля } { отличия-второго-профиля }
  
    opannotate - дизассемблер  | 
  
opannotate создаёт размеченный (аннотированный) листинг исходного кода программы 
(приложение должны быть скомпилировано с отладочной информацией - "gcc -g") и/или
листинг дизассемблера, в который добавляется информация о значении счётчиков. 
Спецификация профиля задаётся аналогично команде opreport.
Ключи:
- --assembly (вывести аннотированный листинг дизассемблера)
 
- --base-dirs=список-каталогов (удалить указанную строку их абсолютных имён файлов с исходных кодом перед поиском)
 
- --demangle | -D {none|smart|normal} (приводить имена функций C++ к человеческому виду)
 
- --exclude-dependent | -x (не включать данные о связанных с программой библиотеках и модулях ядра)
 
- --exclude-file список-шаблонов
 
- --exclude-symbols | -e список-символов (не включать данные о перечисленных символах)
 
- --image-path | -p пути (список путей поиска для программ и модулей ядра - /lib/modules/2.6.18-164.15.1.el5/kernel/)
 
- --include-file список-шаблонов
 
- --include-symbols | -i список-символов (включать данные только о перечисленных символах)
 
- --objdump-params параметры-objdump
 
- --output-dir=каталог (разбить аннотированный листинг по файлам; несовместим с --assembly)
 
- --root | -r путь
 
- --search-dirs=список-каталогов (где искать исходный код)
 
- --source (выести аннотированный листинг исходного кода)
 
- --threshold | -t процентов (не выводить малозначимые данные)
 
Расширение OProfile для Eclipse CDT позволяет исследовать особенности поведения разрабатываемой программы,
не выходя из среды Eclipse.
  
    | 
    
     | 
    Bog BOS: oprofile - исследование особенностей вычислительной производительности с использованием аппаратных счётчиков событий
       
     | 
  
Copyright © 1996-2025 Sergey E. Bogomolov; www.bog.pp.ru