Google ve ack
-ing bitti! Cevabım var.
Ama önce sorunun amacını biraz daha açıklamama izin verin: Sistemdeki bağımsız süreçleri ve performans sayaçlarını açıkça ayırt etmek istiyorum. Örneğin, bir işlemcinin çekirdeği, çekirdeksiz bir cihaz (son zamanlarda öğrenilen), işlemcideki çekirdek veya kullanıcı uygulaması, bir veri yolu (= veri yolu denetleyicisi), bir sabit sürücü tamamen bağımsız süreçlerdir, bir saat ile senkronize edilmezler . Ve bugünlerde muhtemelen hepsinde bazı Süreç İzleme Sayacı (PMC) var. Sayaçların hangi süreçlerden geldiğini anlamak istiyorum. (Ayrıca googling de yararlıdır: bir şey "satıcı" daha iyi sıfırlar.)
Ayrıca, arama için kullanılan dişli: Ubuntu 14.04
,, linux 3.13.0-103-generic
işlemci Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz
( /proc/cpuinfo
2 fiziksel çekirdeğe ve 4 sanal - burada fiziksel meseleye sahiptir).
Terminoloji, sorunun içerdiği şeyler
Intel'den:
işlemci bir core
cihazdır (1 cihaz / süreç) ve bir grup uncore
cihazdır , core
programı çalıştıran şeydir (saat, ALU, kayıtlar vb.), uncore
kalıp üzerine yerleştirilmiş, hız ve düşük gecikme için işlemciye yakın cihazlardır (gerçek sebep "çünkü üretici bunu yapabilir"); anladığım kadarıyla, PC anakartında olduğu gibi temelde Kuzeyköprüsü artı önbellekler; ve AMD aslında bu cihazları instead of
NorthBridge uncore` olarak adlandırıyor;
ubox
ki bu benim sysfs
$ find /sys/devices/ -type d -name events
/sys/devices/cpu/events
/sys/devices/uncore_cbox_0/events
/sys/devices/uncore_cbox_1/events
- uncore
Last Level Cache'i yöneten bir cihazdır (LLC, RAM'e çarpmadan önceki son cihaz); 2 çekirdeğim var, bu yüzden 2 LLC ve 2 ubox
;
İşlemci İzleme Birimi (PMU), bir işlemcinin işlemlerini izleyen ve bunları İşlemci İzleme Sayacına (PMC) kaydeden ayrı bir aygıttır (önbellek hatalarını, işlemci döngülerini vb. Sayar); cihazlarda core
ve uncore
cihazlarda var olurlar ; bunlara (PMC oku) talimatı core
ile erişilir rdpmc
; uncore
bu cihazlar eldeki mevcut işlemci bağımlı olduğundan, ile model Belirli Kayıtları (MAB) üzerinden erişilen rdmsr
(doğal);
görünüşe göre, onlarla iş akışı, kayıt çiftleri aracılığıyla yapılır - sayacın sayıldığı olayları içeren 1 kayıt seti, 2 kayıt sayacın değeridir; sayaç, sadece 1 değil, bir grup olaydan sonra artacak şekilde yapılandırılabilir; + bu sayaçlarda bazı kesintiler / teknoloji fark eden taşmalar var;
Intel'in "IA-32 Yazılım Geliştirici El Kitabı Cilt 3B" bölüm 18 "PERFORMANS İZLEME" bölümünde daha fazlası bulunabilir;
Ayrıca, uncore
MSR'nin bu PMC'ler için somut olarak "Mimari Performans İzleme Sürüm 1" sürümü (kılavuzda 1-4 sürümleri vardır, hangisinin işlemcim olduğunu bilmiyorum) "Şekil 18-1. IA32_PERFEVTSELx MSR'ler "(benimki sayfa 18-3) ve" Tablo 18-1. Önceden Tanımlanmış Mimari Performans Olayları için UMask ve Etkinlik Seçimi Kodlamaları "ile" 18.2.1.2 Önceden Tanımlanmış Mimari Performans Olayları "bölümü olarak gösterilir olaylar Hardware event
içinde perf list
.
Linux çekirdeğinden:
çekirdeğin hem yazılım (çekirdek) hem de donanım olmak üzere farklı menşeli performans sayaçlarını yönetmek için bir sistemi (soyutlama / katman) vardır linux-source-3.13.0/tools/perf/design.txt
; bu sistemdeki bir olay struct perf_event_attr
(dosya linux-source-3.13.0/include/uapi/linux/perf_event.h
) olarak tanımlanır , ana kısmı muhtemelen __u64 config
alanlıdır - hem CPU'ya özgü bir olay tanımını (bu Intel'in rakamlarında açıklanan formatta 64 bitlik kelime) hem de bir çekirdeğin olayını tutabilir
Konfigürasyon kelimesinin MSB'si geri kalanı [ham CPU'lar veya çekirdek olayı] içeriyorsa
çekirdeğin olayı tür için 7 bit ve olay tanımlayıcısı için 56 ile tanımlandı, enum
kodumda -s olan ve benim durumumda:
$ ak PERF_TYPE linux-source-3.13.0/include/
...
linux-source-3.13.0/include/uapi/linux/perf_event.h
29: PERF_TYPE_HARDWARE = 0,
30: PERF_TYPE_SOFTWARE = 1,
31: PERF_TYPE_TRACEPOINT = 2,
32: PERF_TYPE_HW_CACHE = 3,
33: PERF_TYPE_RAW = 4,
34: PERF_TYPE_BREAKPOINT = 5,
36: PERF_TYPE_MAX, /* non-ABI */
( ak
benim takma ack-grep
adı ack
, Debian için adıdır ve ack
harika);
Çekirdeğin kaynak kodunda, "sistemde bulunan tüm PMU'ları kaydet" ve benzer türlere struct pmu
aktarılan yapı türleri gibi işlemler int perf_pmu_register(struct pmu *pmu, const char *name, int type)
görülebilir - böylece, sadece bu sisteme "toplama" PMU "diyebiliriz. sistemdeki tüm PMU'ların; ancak bu ad, yanıltıcı olabilecek çekirdek operasyonlarının izleme sistemi olarak yorumlanabilir;
perf_events
açıklığa kavuşturmak için bu alt sistemi diyelim ;
herhangi bir çekirdek alt sistemi olarak, bu alt sistem dışa aktarılabilir sysfs
(bu, çekirdek alt sistemlerini kişilerin kullanması için dışarı aktarmak için yapılır); ve işte bu events
benim /sys/
dışa aktarılan (? bölümleri) perf_events
alt sistemimdeki dizinler ;
ayrıca, kullanıcı alanı yardımcı programı perf
(linux içine yerleştirilmiş) hala ayrı bir programdır ve kendi soyutlamaları vardır; o kadar kullanıcı tarafından izlenmesi için istenen bir etkinliği gösterdiğini perf_evsel
(dosyalar linux-source-3.13.0/tools/perf/util/evsel.{h,c}
bu yapının bir alan vardır -) struct perf_event_attr attr;
gibi, aynı zamanda bir alan struct cpu_map *cpus;
olduğunu yıllardan nasıl perf
tamamının veya belirli CPU'lar için yarar atar bir olay.
Cevap
Gerçekten de, işlemciye özgü olan ve protokol aracılığıyla erişilebilen Hardware cache event
önbellek aygıtlarının ( ubox
Intel uncore
aygıtlarının) olaylarının "kısayolları" dır Raw hardware event descriptor
. Ve Hardware event
anladığım gibi, core
cihazdaki olayları adlandıran mimari içinde daha kararlı . Diğer 3.13
bazı uncore
olaylara ve sayaçlara çekirdeğimde başka bir "kısayol" yok . Geri kalan her şey - Software
ve Tracepoints
- çekirdeğin olaylardır.
core
'S Hardware event
aynı Raw hardware event descriptor
protokol üzerinden erişilir olup olmadığını merak ediyorum . Sayaç / PMU oturduğundan core
, belki farklı erişilirler. Örneğin, bu rdpmu
talimatla rdmsr
, hangi erişim yerine erişilir uncore
. Ama o kadar önemli değil.
Kernel PMU event
sadece dışa aktarılan olaylardır sysfs
. Bunun nasıl yapıldığını bilmiyorum (otomatik olarak sistemde bulunan tüm PMC'lerin çekirdeği veya sadece kodlanmış bir şey ve eğer eklersem kprobe
- ihraç ediliyor mu? Vb.). Ancak asıl mesele, bunların Hardware event
iç perf_event
sistemdeki veya başka herhangi bir olayla aynı olmasıdır .
Ve bunların ne olduğunu bilmiyorum
$ ls /sys/devices/uncore_cbox_0/events
clockticks
vardır.
İle ilgili ayrıntılar Kernel PMU event
Kodda arama yapmak şunlara yol açar:
$ ak "Kernel PMU" linux-source-3.13.0/tools/perf/
linux-source-3.13.0/tools/perf/util/pmu.c
629: printf(" %-50s [Kernel PMU event]\n", aliases[j]);
- fonksiyonda olan
void print_pmu_events(const char *event_glob, bool name_only) {
...
while ((pmu = perf_pmu__scan(pmu)) != NULL)
list_for_each_entry(alias, &pmu->aliases, list) {...}
...
/* b.t.w. list_for_each_entry is an iterator
* apparently, it takes a block of {code} and runs over some lost
* Ruby built in kernel!
*/
// then there is a loop over these aliases and
loop{ ... printf(" %-50s [Kernel PMU event]\n", aliases[j]); ... }
}
ve perf_pmu__scan
aynı dosyada:
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) {
...
pmu_read_sysfs(); // that's what it calls
}
- aynı dosyada da bulunur:
/* Add all pmus in sysfs to pmu list: */
static void pmu_read_sysfs(void) {...}
Bu kadar.
İlgili ayrıntılar Hardware event
veHardware cache event
Görünüşe göre Hardware event
Intel, IA-32 Software Developer's Cilt 3B'de "Önceden Tanımlanmış Mimari Performans Olayları", 18.2.1.2 dediği şeyden geliyor. Kılavuzun "18.1 PERFORMANS İZLEME GENEL BAKIŞI" bunları şöyle açıklar:
Performans izleme yeteneklerinin ikinci sınıfına mimari performans izleme denir. Bu sınıf, daha az sayıda kullanılabilir olayla aynı sayma ve Kesme tabanlı olay örnekleme kullanımlarını destekler. Mimari performans olaylarının görünür davranışı işlemci uygulamaları arasında tutarlıdır. Mimari performans izleme yeteneklerinin kullanılabilirliği CPUID.0AH kullanılarak numaralandırılır. Bu olaylar Bölüm 18.2'de tartışılmaktadır.
- diğer tür:
Intel Core Solo ve Intel Core Duo işlemcilerden başlayarak, iki sınıf performans izleme kapasitesi vardır. Birinci sınıf, sayma veya kesime dayalı olay örnekleme kullanımını kullanarak performansı izlemek için olayları destekler. Bu olaylar mimari değildir ve bir işlemci modelinden diğerine değişir ...
Ve bu olaylar aslında sadece perf
yardımcı program aracılığıyla erişilebilir altta yatan "ham" donanım olayları için bağlantılar vardır Raw hardware event descriptor
.
Bunu kontrol etmek için şunlara bakar linux-source-3.13.0/arch/x86/kernel/cpu/perf_event_intel.c
:
/*
* Intel PerfMon, used on Core and later.
*/
static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
{
[PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
[PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
...
}
- ve tam olarak 0x412e
"LLC Misses" için Önceden Tanımlanmış Mimari Performans Olayları için "Tablo 18-1. UMask ve Etkinlik Seçimi Kodlamaları" nda bulunur:
Bit Position CPUID.AH.EBX | Event Name | UMask | Event Select
...
4 | LLC Misses | 41H | 2EH
- H
hex içindir. Tüm 7 yapıda, artı [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding *
. (Adlandırma biraz farklı, adresler aynı.)
Sonra Hardware cache event
s (aynı dosyada) gibi yapılardadır:
static __initconst const u64 snb_hw_cache_extra_regs
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
{...}
- kumlu köprü için hangisi olmalı?
Bunlardan biri - yukarıdaki def-s'den nerede snb_hw_cache_extra_regs[LL][OP_WRITE][RESULT_ACCESS]
ile doldurulur SNB_DMND_WRITE|SNB_L3_ACCESS
:
#define SNB_L3_ACCESS SNB_RESP_ANY
#define SNB_RESP_ANY (1ULL << 16)
#define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO)
#define SNB_DMND_RFO (1ULL << 1)
#define SNB_LLC_RFO (1ULL << 8)
Bu eşit olmalı 0x00010102
, ama bazı tablo ile nasıl kontrol bilmiyorum.
Ve bu, nasıl kullanıldığı hakkında bir fikir verir perf_events
:
$ ak hw_cache_extra_regs linux-source-3.13.0/arch/x86/kernel/cpu/
linux-source-3.13.0/arch/x86/kernel/cpu/perf_event.c
50:u64 __read_mostly hw_cache_extra_regs
292: attr->config1 = hw_cache_extra_regs[cache_type][cache_op][cache_result];
linux-source-3.13.0/arch/x86/kernel/cpu/perf_event.h
521:extern u64 __read_mostly hw_cache_extra_regs
linux-source-3.13.0/arch/x86/kernel/cpu/perf_event_intel.c
272:static __initconst const u64 snb_hw_cache_extra_regs
567:static __initconst const u64 nehalem_hw_cache_extra_regs
915:static __initconst const u64 slm_hw_cache_extra_regs
2364: memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
2365: sizeof(hw_cache_extra_regs));
2407: memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
2408: sizeof(hw_cache_extra_regs));
2424: memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
2425: sizeof(hw_cache_extra_regs));
2452: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
2453: sizeof(hw_cache_extra_regs));
2483: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
2484: sizeof(hw_cache_extra_regs));
2516: memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
$
memcpy
S yapılır __init int intel_pmu_init(void) {... case:...}
.
Sadece attr->config1
biraz tuhaf. Ama orada, perf_event_attr
(aynı linux-source-3.13.0/include/uapi/linux/perf_event.h
dosyada):
...
union {
__u64 bp_addr;
__u64 config1; /* extension of config */
};
union {
__u64 bp_len;
__u64 config2; /* extension of config1 */
};
...
Çekirdek perf_events
sistemine kayıtlı int perf_pmu_register(struct pmu *pmu, const char *name, int type)
(içinde tanımlanmış linux-source-3.13.0/kernel/events/core.c:
) çağrılar ile kayıtlıdırlar :
static int __init init_hw_perf_events(void)
arch/x86/kernel/cpu/perf_event.c
çağrı ile (dosya )perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
(dosya arch/x86/kernel/cpu/perf_event_intel_uncore.c
, ayrıca var arch/x86/kernel/cpu/perf_event_amd_uncore.c
) çağrı ileret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
Son olarak, tüm olaylar donanımdan geliyor ve her şey yolunda. Ama burada bir fark olabilir: neden var LLC-loads
içinde perf list
değil ubox1 LLC-loads
bunlar HW olaylardır beri ve bunlar aslında gelen ubox
es?
Bu perf
yardımcı programın ve onun perf_evsel
yapısının bir şeyidir: sizden bir HW olayı perf
istediğinizde, onu istediğiniz işlemcileri tanımlayın (varsayılan hepsi) ve perf_evsel
istenen olay ve işlemcilerle kurar , ardından toplama içindeki tüm işlemcilerden gelen sayaçları toplar perf_evsel
(veya onlarla başka istatistikler yapar).
Birisi bunu görebilir tools/perf/builtin-stat.c
:
/*
* Read out the results of a single counter:
* aggregate counts across CPUs in system-wide mode
*/
static int read_counter_aggr(struct perf_evsel *counter)
{
struct perf_stat *ps = counter->priv;
u64 *count = counter->counts->aggr.values;
int i;
if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter),
thread_map__nr(evsel_list->threads), scale) < 0)
return -1;
for (i = 0; i < 3; i++)
update_stats(&ps->res_stats[i], count[i]);
if (verbose) {
fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
perf_evsel__name(counter), count[0], count[1], count[2]);
}
/*
* Save the full runtime - to allow normalization during printout:
*/
update_shadow_stats(counter, count);
return 0;
}
(Bu nedenle, yardımcı program perf
için "tek sayaç", perf_event_attr
genel bir form olan ve hem SW hem de HW olaylarını sığdıran bir sorgu değildir, sorgunuzun bir olayıdır - aynı olaylar farklı cihazlardan gelebilir ve toplanır .)
Ayrıca bir uyarı: struct perf_evsel
sadece 1 içerir struct perf_evevent_attr
, ancak aynı zamanda bir alanı vardır struct perf_evsel *leader;
- iç içe. perf_events
Bir grup sayacı birlikte gönderebileceğiniz ve birbirleriyle karşılaştırılabilecekleri "(hiyerarşik) olay grupları" özelliği vardır . Değil emin bağımsız olaylar ile nasıl çalıştığını kernel
, core
, ubox
. Ama bu iç içe geçmiş perf_evsel
. Ve büyük olasılıkla, perf
birkaç olayın sorgusunu birlikte yönetir.