Başka hangi programlar gprof ile aynı şeyi yapar?
Başka hangi programlar gprof ile aynı şeyi yapar?
Yanıtlar:
Valgrind , KCacheGrind adında çok hoş bir görselleştiriciye sahip bir talimat sayıcı profiline sahiptir . Mike Dunlavey'nin önerdiği gibi, Valgrind, bir prosedürün yığın üzerinde canlı olduğu talimatların bir kısmını sayar, ancak karşılıklı özyineleme ile karıştırıldığını söylediğim için üzgünüm. Ancak görselleştirici çok güzel ve hafif yıllar öncesinde gprof
.
gprof (makaleyi okuyun) tarihsel nedenlerden dolayı mevcuttur. Performans sorunlarını bulmanıza yardımcı olacağını düşünüyorsanız, asla böyle ilan edilmemiştir. Makalenin söyledikleri:
Prole, çeşitli uygulamaların maliyetlerini karşılaştırmak ve değerlendirmek için kullanılabilir.
Özel durumlarda değerlendirilebileceği anlamına gelse de, değerlendirilecek çeşitli uygulamaları tanımlamak için kullanılabileceğini söylemez :
özellikle programın küçük bölümlerinin yürütme süresine hakim olduğu görülürse.
Bu kadar yerelleştirilmemiş sorunlara ne dersiniz? Bunlar önemli değil mi? Asla iddia edildi gprof beklentileri koymayın. Bu sadece bir ölçüm aracıdır ve sadece CPU'ya bağlı işlemlerdir.
Bunun yerine bunu deneyin.
İşte 44x hızlanma örneği.
İşte 730x hızlanma.
İşte 8 dakikalık bir video gösterisi.
İşte istatistiklerin bir açıklaması.
İşte eleştirilere bir cevap.
Programlar hakkında basit bir gözlem var. Belirli bir infazda, her talimat, call
orada olmasaydı, zamanın harcanmayacağı anlamında , toplam sürenin bir kısmından (özellikle talimatlar) sorumludur . Bu süre zarfında, talimat yığın üzerindedir **. Bu anlaşıldığında bunu görebilirsiniz -
gprof , performansla ilgili belirli mitleri içerir, örneğin:
bu program karşı örnekleme kullanışlıdır.
Sadece büyük bir skaler değer dizisi gibi gereksiz bir sıcak nokta darboğunuz varsa yararlıdır. Örneğin, string-Compare'i kullanarak bir sıralama olarak değiştirir değiştirmez, yine de bir darboğazdır, ancak program karşı örnekleme bunu görmez, çünkü şimdi hotspot string-karşılaştırmasındadır. Öte yandan, genişletilmiş program sayacını (çağrı yığını) örnekleyecek olsaydı , dize karşılaştırmasının çağrıldığı nokta, sıralama döngüsü açıkça görüntülenir. Aslında, gprof sadece pc örneklemesinin sınırlamalarını düzeltmek için bir girişimdi.
zamanlama fonksiyonlarının zaman alan kod satırlarını yakalamaktan daha önemlidir.
Bu efsanenin nedeni, gprof'un yığın örneklerini yakalayamamasıdır, bunun yerine işlevleri zamanlar, çağrılarını sayar ve çağrı grafiğini yakalamaya çalışır. Bununla birlikte, maliyetli bir fonksiyon tanımlandıktan sonra, zamandan sorumlu olan hatlar için hala onun içine bakmanız gerekir. Bakmanız gerekmeyen yığın örnekleri olsaydı, bu çizgiler örneklerin üzerindeydi. (Tipik bir fonksiyonun 100 - 1000 talimatları olabilir. Bir fonksiyon çağrısı 1 talimattır, bu nedenle pahalı çağrıları bulan bir şey 2-3 büyüklük derecesinde daha hassastır.)
çağrı grafiğinin önemli olduğunu.
Bir program hakkında bilmeniz gereken şey, zamanını nerede geçirdiği değil , neden. Bir işlevde zaman harcıyorsa, yığındaki her kod satırı, neden orada olduğuna dair akıl yürütme zincirinde bir bağlantı verir. Yığının yalnızca bir kısmını görebiliyorsanız, nedeninin yalnızca bir kısmını görebilirsiniz, bu nedenle o zamanın gerçekten gerekli olup olmadığından emin olamazsınız. Çağrı grafiği size ne anlatıyor? Her yay, bazı A işlevinin zamanın bir kısmı için bazı B işlevini çağırma sürecinde olduğunu söyler. A'nın B'yi çağıran böyle bir kod satırı olsa bile, bu satırın nedeninin sadece küçük bir kısmını verir. Yeterince şanslıysanız, belki de bu hattın kötü bir nedeni vardır. Genellikle, varsa kötü bir neden bulmak için birden fazla eşzamanlı çizgi görmeniz gerekir. A, B'yi birden fazla yerde ararsa, size daha da azını söyler.
bu özyineleme karmaşık bir konudur.
Bunun nedeni, yalnızca gprof ve diğer profil kullanıcılarının bir çağrı grafiği oluşturma ve ardından düğümlere zaman atfetme ihtiyacını algılamalarıdır. Yığının örnekleri varsa, örneklerde görünen her kod satırının zaman maliyeti çok basit bir sayıdır - örneklerin üzerinde olduğu kısım. Özyineleme varsa, belirli bir çizgi bir örnekte birden çok kez görünebilir.
Önemli değil. Örneklerin her N ms'de alındığını ve çizginin% F'sinde (tek başına veya tek başına) göründüğünü varsayalım. Eğer bu çizgi hiç zaman almayacaksa (örneğin silinerek veya dallara ayrılarak), o zaman bu örnekler kaybolacak ve zaman% F oranında azalacaktır.
zaman ölçümünün doğruluğu (ve dolayısıyla çok sayıda örnek) önemlidir.
Bir saniye düşünün. Beş satırdan 3 tanesinde bir kod satırı varsa, ampul gibi fırlatabilirseniz, bu yaklaşık% 60 daha az zaman harcar. Şimdi, farklı bir 5 numune almış olsaydınız, bunu sadece 2 kez veya 4'e kadar görmüş olabilirsiniz. Böylece,% 60'lık ölçüm,% 40 ila% 80 arasındaki genel bir aralığa benzer. Sadece% 40 olsaydı, sorunun düzeltilmeye değmediğini söyleyebilir misiniz? Peki, zamanın doğruluğu nedir, gerçekten istediğiniz şey problemleri bulmak olduğunda ? 500 veya 5000 numune sorunu daha hassas bir şekilde ölçecek, ancak daha doğru bir şekilde bulamazdı.
ifade veya işlev çağırmalarının sayılmasının yararlı olduğunu.
Bir işlevin 1000 kez çağrıldığını bildiğinizi varsayalım. Bundan ne kadar zaman harcadığını söyleyebilir misiniz? Ayrıca, koşmanın ortalama olarak ne kadar süreceğini bilmeniz gerekir, bunu sayı ile çarpın ve toplam süreye bölün. Ortalama invokasyon süresi nanosaniyeden saniyelere değişebilir, bu nedenle tek başına sayı çok fazla anlatmaz. Yığın örnekleri varsa, bir rutinin veya herhangi bir ifadenin maliyeti, üzerinde bulunduğu örneklerin sadece bir kısmıdır. Zamanın bu kısmı, rutin veya ifadenin hiç zaman almaması için prensip olarak kurtarılabilecek şeydir, bu nedenle performansla en doğrudan ilişki budur.
bloke edildiğinde örnek alınmasına gerek yoktur
Bu mitin nedenleri iki yönlüdür: 1) program beklerken PC örneklemesinin anlamsız olması ve 2) zamanlamanın doğruluğu ile meşguliyet. Bununla birlikte, (1) için program, bilmeniz gereken dosya G / Ç ve hangi yığın örneklerinin ortaya çıkardığı gibi istediği bir şeyi bekliyor olabilir . (Açıkçası kullanıcı girişini beklerken örnekleri hariç tutmak istersiniz.) (2) için, program sadece diğer süreçlerle rekabet nedeniyle bekliyorsa, bu muhtemelen çalışırken oldukça rastgele bir şekilde gerçekleşir. Dolayısıyla, program daha uzun sürebilirken, bunun önemli olan istatistik üzerinde büyük bir etkisi olmayacak olsa da, ifadelerin yığın üzerinde bulunduğu sürenin yüzdesi.
"kendinden zaman" önemlidir
Kendinden zaman, yalnızca hat düzeyinde değil, fonksiyon düzeyinde ölçüm yapıyorsanız anlamlıdır ve fonksiyon süresi, çağrılan rutinlere kıyasla tamamen yerel hesaplamaya giriyorsa, ayırt etme konusunda yardıma ihtiyacınız olduğunu düşünürsünüz. Eğer çizgi seviyesinde özetleniyorsa, bir satır yığının sonundaysa kendi kendine zamanı, aksi halde kapsayıcı zamanı temsil eder. Her iki durumda da, maliyeti, üzerinde olduğu yığın örneklerinin yüzdesidir, böylece her iki durumda da sizin için bulur.
örneklerin yüksek frekansta alınması gerektiğinde
Bu, bir performans sorununun hızlı etkili olabileceği ve örneklerin vurmak için sık olması gerektiği fikrinden gelir. Ancak, sorun, toplam 10 saniyelik (veya her ne olursa olsun) toplam çalışma süresinden% 20'se mal oluyorsa, o zamanki her bir örnek, sorun olursa olsun,% 20'lik bir isabet şansına sahip olacaktır. bunun gibi tek bir parçada
.....XXXXXXXX...........................
.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^
(20 numune, 4 isabet)
veya bunun gibi birçok küçük parçada
X...X...X.X..X.........X.....X....X.....
.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^
(20 numune, 3 isabet)
Her iki durumda da, kaç numune alınırsa alınsın isabet sayısı ortalama 5'te 1 olur veya ne kadar az. (Ortalama = 20 * 0.2 = 4. Standart sapma = +/- sqrt (20 * 0.2 * 0.8) = 1.8.)
bulmaya çalıştığınız olduğu darboğaz
tek varmış gibi. Aşağıdaki yürütme zaman çizelgesini göz önünde bulundurun: ile vxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
temsil edilen gerçek yararlı çalışmalardan oluşur .
. vWxYz
Zamanın 1/2, 1/4, 1/8, 1/16, 1/32'sini alan performans sorunları vardır . Örnekleme v
kolayca bulunur. Kaldırılır, ayrılır
xWzWxWYWxW.WxWYW
Şimdi programın çalışması yarıya kadar uzun W
sürer ve şimdi yarı zaman alır ve kolayca bulunur. Kaldırılır, bırakılır
xzxYx.xY
Bu işlem , kaldırılacak hiçbir şey bulunamayana kadar en büyük performans yüzdesi sorununu her seferinde kaldırarak devam eder. Şimdi yürütülen tek şey .
, orijinal program tarafından kullanılan sürenin 1 / 32'sinde yürütülür . Bu büyütme etkisidir, herhangi bir sorunun kaldırılması, kalanları yüzde olarak büyütür, çünkü payda azalır.
Bir diğer önemli nokta da her sorunun bulunması gerektiğidir - 5'in hiçbirini eksik. Bulunmayan ve giderilen herhangi bir sorun nihai hızlanma oranını ciddi şekilde azaltır. Sadece bazılarını bulmak, ama hepsi değil, "yeterince iyi" değildir.
EKLENDİ: Sadece gprof'un popüler olmasının bir nedenine dikkat çekmek istiyorum - muhtemelen ücretsiz, öğretmesi kolay olduğu ve uzun süredir öğretildiği için öğretiliyor. Hızlı bir Google araması, bunu öğreten (veya öyle görünen) bazı akademik kurumları bulur:
berkeley bu clemson colorado dük earlham fsu indiana mit msu ncsa.illinois ncsu nyu ou princeton psu stanford ucsd umd umich utah utexas utk wustl
** İşin yapılmasını istemenin diğer yolları dışında, mesaj gönderme gibi nedenini söyleyen bir iz bırakmaz .
Burada perf
, Linux'ta çekirdek ve kullanıcı uygulamalarının profilini oluşturmak için nispeten yeni bir araç olan hiçbir şey görmediğimden , bu bilgileri eklemeye karar verdim.
Her şeyden önce - bu Linux profilleme ile ilgili bir öğreticidirperf
Sen kullanabilirsiniz perf
Linux Kernel büyük 2.6.32 veya daha ise oprofile
o eski ise. Her iki program da sizden programınızı düzenlemenizi gprof
gerektirmez (gibi ). Ancak arama grafiğini doğru bir şekilde alabilmek için perf
program oluşturmanız gerekiyor -fno-omit-frame-pointer
. Örneğin: g++ -fno-omit-frame-pointer -O2 main.cpp
.
Başvurunuzun "canlı" analizini şununla görebilirsiniz perf top
:
sudo perf top -p `pidof a.out` -K
Veya çalışan bir uygulamanın performans verilerini kaydedebilir ve bundan sonra bunları analiz edebilirsiniz:
1) Performans verilerini kaydetmek için:
perf record -p `pidof a.out`
veya 10 saniye kayıt yapmak için:
perf record -p `pidof a.out` sleep 10
veya çağrı grafiğiyle () kayıt yapmak için
perf record -g -p `pidof a.out`
2) Kaydedilen verileri analiz etmek
perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g
Veya bir uygulamanın performans verilerini kaydedebilir ve bundan sonra uygulamayı bu şekilde başlatarak ve çıkmasını bekleyerek analiz edebilirsiniz:
perf record ./a.out
Bu, bir test programının profilini oluşturmaya bir örnektir
Test programı main.cpp dosyasında (iletinin altına main.cpp koyacağım):
Bu şekilde derliyorum:
g++ -m64 -fno-omit-frame-pointer -g main.cpp -L. -ltcmalloc_minimal -o my_test
Ben libc malloc bu seçenek olmadan derlenmiş gibi görünüyor iken libmalloc_minimial.so
ile derlenmiş beri -fno-omit-frame-pointer
kullanın. Sonra test programımı çalıştırıyorum
./my_test 100000000
Sonra çalışan bir işlemin performans verilerini kaydederim:
perf record -g -p `pidof my_test` -o ./my_test.perf.data sleep 30
Sonra modül başına yükü analiz ediyorum:
mükemmel rapor - stdio -g hiçbiri --sort comm, dso -i ./my_test.perf.data
# Overhead Command Shared Object
# ........ ....... ............................
#
70.06% my_test my_test
28.33% my_test libtcmalloc_minimal.so.0.1.0
1.61% my_test [kernel.kallsyms]
Daha sonra fonksiyon başına yük analiz edilir:
perf raporu --stdio -g none -i ./my_test.perf.data | c ++ filt
# Overhead Command Shared Object Symbol
# ........ ....... ............................ ...........................
#
29.30% my_test my_test [.] f2(long)
29.14% my_test my_test [.] f1(long)
15.17% my_test libtcmalloc_minimal.so.0.1.0 [.] operator new(unsigned long)
13.16% my_test libtcmalloc_minimal.so.0.1.0 [.] operator delete(void*)
9.44% my_test my_test [.] process_request(long)
1.01% my_test my_test [.] operator delete(void*)@plt
0.97% my_test my_test [.] operator new(unsigned long)@plt
0.20% my_test my_test [.] main
0.19% my_test [kernel.kallsyms] [k] apic_timer_interrupt
0.16% my_test [kernel.kallsyms] [k] _spin_lock
0.13% my_test [kernel.kallsyms] [k] native_write_msr_safe
and so on ...
Ardından çağrı zincirleri analiz edilir:
mükemmel rapor - stdio -g grafiği -i ./my_test.perf.data | c ++ filt
# Overhead Command Shared Object Symbol
# ........ ....... ............................ ...........................
#
29.30% my_test my_test [.] f2(long)
|
--- f2(long)
|
--29.01%-- process_request(long)
main
__libc_start_main
29.14% my_test my_test [.] f1(long)
|
--- f1(long)
|
|--15.05%-- process_request(long)
| main
| __libc_start_main
|
--13.79%-- f2(long)
process_request(long)
main
__libc_start_main
15.17% my_test libtcmalloc_minimal.so.0.1.0 [.] operator new(unsigned long)
|
--- operator new(unsigned long)
|
|--11.44%-- f1(long)
| |
| |--5.75%-- process_request(long)
| | main
| | __libc_start_main
| |
| --5.69%-- f2(long)
| process_request(long)
| main
| __libc_start_main
|
--3.01%-- process_request(long)
main
__libc_start_main
13.16% my_test libtcmalloc_minimal.so.0.1.0 [.] operator delete(void*)
|
--- operator delete(void*)
|
|--9.13%-- f1(long)
| |
| |--4.63%-- f2(long)
| | process_request(long)
| | main
| | __libc_start_main
| |
| --4.51%-- process_request(long)
| main
| __libc_start_main
|
|--3.05%-- process_request(long)
| main
| __libc_start_main
|
--0.80%-- f2(long)
process_request(long)
main
__libc_start_main
9.44% my_test my_test [.] process_request(long)
|
--- process_request(long)
|
--9.39%-- main
__libc_start_main
1.01% my_test my_test [.] operator delete(void*)@plt
|
--- operator delete(void*)@plt
0.97% my_test my_test [.] operator new(unsigned long)@plt
|
--- operator new(unsigned long)@plt
0.20% my_test my_test [.] main
0.19% my_test [kernel.kallsyms] [k] apic_timer_interrupt
0.16% my_test [kernel.kallsyms] [k] _spin_lock
and so on ...
Bu noktada programınızın nerede zaman harcadığını biliyorsunuz.
Ve bu test için main.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
time_t f1(time_t time_value)
{
for (int j =0; j < 10; ++j) {
++time_value;
if (j%5 == 0) {
double *p = new double;
delete p;
}
}
return time_value;
}
time_t f2(time_t time_value)
{
for (int j =0; j < 40; ++j) {
++time_value;
}
time_value=f1(time_value);
return time_value;
}
time_t process_request(time_t time_value)
{
for (int j =0; j < 10; ++j) {
int *p = new int;
delete p;
for (int m =0; m < 10; ++m) {
++time_value;
}
}
for (int i =0; i < 10; ++i) {
time_value=f1(time_value);
time_value=f2(time_value);
}
return time_value;
}
int main(int argc, char* argv2[])
{
int number_loops = argc > 1 ? atoi(argv2[1]) : 1;
time_t time_value = time(0);
printf("number loops %d\n", number_loops);
printf("time_value: %d\n", time_value );
for (int i =0; i < number_loops; ++i) {
time_value = process_request(time_value);
}
printf("time_value: %ld\n", time_value );
return 0;
}
f1
arıyordu delete
. Zamanın% 40'ı (kabaca) process_request
arıyordu delete
. Kalanın iyi bir kısmı harcanmıştı new
. Ölçümler pürüzlüdür, ancak sıcak noktalar kesin olarak belirlenir.
As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace
. 1) Müşterinizin sunucusunda çalışan bir programın performans sorunlarını analiz etmeniz gerektiğinde tekniğinizin yararlı olmadığını düşünüyorum. 2) Farklı istekleri işleyen birçok iş parçacığı olan bir program hakkında bilgi almak için bu tekniği nasıl uyguladığınızdan emin değilim. Genel tablo oldukça karmaşık olduğunda.
the problem is outside your code
mi? Puanınızı desteklemek için bazı bilgilere ihtiyacınız olabileceğinden. Bu durumda, bir noktada başvurunuzu profillemeniz gerekebilir. Müşterinizden gdb'yi başlatmasını ve ^ C tuşuna basarak çağrı yığınları almasını isteyemezsiniz. Demek istediğim bu. Bu bir örnek spielwiese.fontein.de/2012/01/22/… . Bu sorunu yaşadım ve profilleme çok yardımcı oldu.
OProfile'ı deneyin . Kodunuzun profilini çıkarmak için çok daha iyi bir araçtır. Intel VTune'i de öneririm .
Yukarıdaki iki araç, belirli bir kod satırında harcanan zamanı daraltabilir, kodunuza açıklama ekleyebilir, montajı ve ne kadar özel talimat gerektiğini gösterebilir. Zaman metriğinin yanı sıra belirli sayaçları, yani önbellek isabetlerini vb. Sorgulayabilirsiniz.
Gprof'den farklı olarak, sisteminizde çalışan herhangi bir işlemi / ikili dosyayı bu ikisinden birini kullanarak profilleyebilirsiniz.
Google performans araçları , kullanımı kolay bir profil oluşturucu içerir. CPU ve yığın profiler mevcuttur.
Sysprof'a bir göz atın .
Dağıtımınızda zaten olabilir.
Yüksek performanslı bir izleyici istiyorsanız http://lttng.org/