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-genericişlemci Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz( /proc/cpuinfo2 fiziksel çekirdeğe ve 4 sanal - burada fiziksel meseleye sahiptir).
Terminoloji, sorunun içerdiği şeyler
Intel'den:
işlemci bir corecihazdır (1 cihaz / süreç) ve bir grup uncorecihazdır , coreprogramı çalıştıran şeydir (saat, ALU, kayıtlar vb.), uncorekalı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 ofNorthBridge 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
- uncoreLast 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 coreve uncorecihazlarda var olurlar ; bunlara (PMC oku) talimatı coreile erişilir rdpmc; uncorebu 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, uncoreMSR'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 eventiç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 configalanlı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ı, enumkodumda -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 */
( akbenim takma ack-grepadı ack, Debian için adıdır ve ackharika);
Çekirdeğin kaynak kodunda, "sistemde bulunan tüm PMU'ları kaydet" ve benzer türlere struct pmuaktarı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_eventsaçı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 eventsbenim /sys/dışa aktarılan (? bölümleri) perf_eventsalt 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 perftamamı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 ( uboxIntel uncoreaygıtlarının) olaylarının "kısayolları" dır Raw hardware event descriptor. Ve Hardware eventanladığım gibi, corecihazdaki olayları adlandıran mimari içinde daha kararlı . Diğer 3.13bazı uncoreolaylara ve sayaçlara çekirdeğimde başka bir "kısayol" yok . Geri kalan her şey - Softwareve Tracepoints- çekirdeğin olaylardır.
core'S Hardware eventaynı Raw hardware event descriptorprotokol üzerinden erişilir olup olmadığını merak ediyorum . Sayaç / PMU oturduğundan core, belki farklı erişilirler. Örneğin, bu rdpmutalimatla rdmsr, hangi erişim yerine erişilir uncore. Ama o kadar önemli değil.
Kernel PMU eventsadece 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 eventiç perf_eventsistemdeki 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__scanaynı 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 eventveHardware cache event
Görünüşe göre Hardware eventIntel, 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 perfyardı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
- Hhex 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 events (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));
$
memcpyS yapılır __init int intel_pmu_init(void) {... case:...}.
Sadece attr->config1biraz tuhaf. Ama orada, perf_event_attr(aynı linux-source-3.13.0/include/uapi/linux/perf_event.hdosyada):
...
union {
__u64 bp_addr;
__u64 config1; /* extension of config */
};
union {
__u64 bp_len;
__u64 config2; /* extension of config1 */
};
...
Çekirdek perf_eventssistemine 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-loadsiçinde perf listdeğil ubox1 LLC-loadsbunlar HW olaylardır beri ve bunlar aslında gelen uboxes?
Bu perfyardımcı programın ve onun perf_evselyapısının bir şeyidir: sizden bir HW olayı perfistediğinizde, onu istediğiniz işlemcileri tanımlayın (varsayılan hepsi) ve perf_evselistenen 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 perfiçin "tek sayaç", perf_event_attrgenel 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_evselsadece 1 içerir struct perf_evevent_attr, ancak aynı zamanda bir alanı vardır struct perf_evsel *leader;- iç içe. perf_eventsBir 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, perfbirkaç olayın sorgusunu birlikte yönetir.