Profiling
CPU Profiling
CPU profilinin julia kodunu analiz etmenin iki ana yaklaşımı vardır:
Via @profile
Veri bir çağrı için @profile
makrosu aracılığıyla profil oluşturmanın etkin olduğu yer.
julia> using Profile
julia> @profile foo()
julia> Profile.print()
Overhead ╎ [+additional indent] Count File:Line; Function
=========================================================
╎147 @Base/client.jl:506; _start()
╎ 147 @Base/client.jl:318; exec_options(opts::Base.JLOptions)
...
Triggered During Execution
Zaten çalışan görevler, kullanıcı tarafından tetiklenen herhangi bir zamanda sabit bir süre boyunca da profil oluşturulabilir.
Profiling'i tetiklemek için:
- MacOS ve FreeBSD (BSD tabanlı platformlar):
ctrl-t
kullanın veya julia sürecine birSIGINFO
sinyali gönderin, yani% kill -INFO $julia_pid
- Linux:
julia
sürecineSIGUSR1
sinyali gönderin, yani% kill -USR1 $julia_pid
- Windows: Şu anda desteklenmiyor.
İlk olarak, sinyalin atıldığı anda tek bir yığın izinin gösterildiği, ardından 1 saniyelik bir profilin toplandığı ve sonraki yield noktasında profil raporunun verildiği, yield noktaları olmayan kodlar için görev tamamlanmasında (örneğin, sıkı döngüler) olabileceği belirtilmektedir.
İsteğe bağlı olarak, ortam değişkenini JULIA_PROFILE_PEEK_HEAP_SNAPSHOT
değerini 1
olarak ayarlayın, böylece otomatik olarak heap snapshot toplayabilirsiniz.
julia> foo()
##== the user sends a trigger while foo is running ==##
load: 2.53 cmd: julia 88903 running 6.16u 0.97s
======================================================================================
Information request received. A stacktrace will print followed by a 1.0 second profile
======================================================================================
signal (29): Information request: 29
__psynch_cvwait at /usr/lib/system/libsystem_kernel.dylib (unknown line)
_pthread_cond_wait at /usr/lib/system/libsystem_pthread.dylib (unknown line)
...
======================================================================
Profile collected. A report will print if the Profile module is loaded
======================================================================
Overhead ╎ [+additional indent] Count File:Line; Function
=========================================================
Thread 1 Task 0x000000011687c010 Total snapshots: 572. Utilization: 100%
╎147 @Base/client.jl:506; _start()
╎ 147 @Base/client.jl:318; exec_options(opts::Base.JLOptions)
...
Thread 2 Task 0x0000000116960010 Total snapshots: 572. Utilization: 0%
╎572 @Base/task.jl:587; task_done_hook(t::Task)
╎ 572 @Base/task.jl:879; wait()
...
Customization
Profiling süresini Profile.set_peek_duration
aracılığıyla ayarlayabilirsiniz.
Profil raporu, iş parçacığı ve görev bazında ayrılmıştır. Bunu geçersiz kılmak için Profile.peek_report[]
'a argüman almayan bir fonksiyon geçirin. Yani, gruplamayı kaldırmak için Profile.peek_report[] = () -> Profile.print()
kullanın. Bu, harici bir profil veri tüketicisi tarafından da geçersiz kılınabilir.
Reference
Profile.@profile
— Macro@profil
@profil <ifade>
ifadenizi periyodik geri izlemeler alarak çalıştırır. Bunlar, geri izlemelerin dahili bir tamponuna eklenir.
Profile
içindeki yöntemler dışa aktarılmamış ve Profile.print()
gibi çağrılması gerekiyor.
Profile.clear
— Functionclear()
Mevcut geri izleri iç tampondan temizler.
Profile.print
— Functionprint([io::IO = stdout,] [data::Vector = fetch()], [lidict::Union{LineInfoDict, LineInfoFlatDict} = getdict(data)]; kwargs...)
Profiling sonuçlarını io
ya (varsayılan olarak stdout
) yazdırır. Eğer bir data
vektörü sağlamazsanız, birikmiş geri izlerin içsel tamponu kullanılacaktır.
Anahtar argümanlar herhangi bir kombinasyon olabilir:
format
– Geri izlerin ağaç yapısını gösteren (varsayılan,:tree
) veya göstermeyen (:flat
) girintili olarak yazdırılıp yazdırılmayacağını belirler.C
– Eğertrue
ise, C ve Fortran kodlarından geri izler gösterilir (normalde hariç tutulur).combine
– Eğertrue
(varsayılan), aynı kod satırına karşılık gelen talimat işaretçileri birleştirilir.maxdepth
–:tree
formatındamaxdepth
'ten daha derinliği sınırlar.sortedby
–:flat
formatındaki sıralamayı kontrol eder.:filefuncline
(varsayılan) kaynak satırına göre sıralar,:count
toplanan örnek sayısına göre sıralar ve:overhead
her fonksiyonun kendisi tarafından neden olunan örnek sayısına göre sıralar.groupby
– Görevler ve iş parçacıkları üzerinde gruplamayı veya gruplama olmamasını kontrol eder. Seçenekler:none
(varsayılan),:thread
,:task
,[:thread, :task]
veya[:task, :thread]
'dir; son iki seçenek iç içe gruplama sağlar.noisefloor
– Örneklerin sezgisel gürültü tabanını aşan çerçeveleri sınırlar (sadece:tree
formatına uygulanır). Bunun için denemek için önerilen bir değer 2.0'dır (varsayılan 0'dır). Bu parametre,n <= noisefloor * √N
olan satırlar için örnekleri gizler; buradan
bu satırdaki örnek sayısı veN
çağrılan için örnek sayısıdır.mincount
– Yazdırmayı yalnızca en azmincount
kez bulunan satırlarla sınırlar.recur
–:tree
formatındaki özyineleme işlemlerini kontrol eder.:off
(varsayılan) ağacı normal olarak yazdırır.:flat
bunun yerine herhangi bir özyinelemeyi (ip ile) sıkıştırır ve herhangi bir kendine özyinelemeyi bir yineleyiciye dönüştürmenin yaklaşık etkisini gösterir.:flatc
aynı şeyi yapar ancak ayrıca C çerçevelerinin çökmesini de içerir (belirli durumlardajl_apply
etrafında garip şeyler yapabilir).threads::Union{Int,AbstractVector{Int}}
– Raporun hangi iş parçacıklarından anlık görüntüler içereceğini belirtir. Bunun, hangi iş parçacıklarında örneklerin toplandığını kontrol etmediğini unutmayın (bu örnekler başka bir makinede de toplanmış olabilir).tasks::Union{Int,AbstractVector{Int}}
– Raporun hangi görevlerden anlık görüntüler içereceğini belirtir. Bunun, hangi görevlerde örneklerin toplandığını kontrol etmediğini unutmayın.
groupby
, threads
ve tasks
anahtar argümanları Julia 1.8'de tanıtılmıştır.
Windows'ta profil oluşturma ana iş parçacığı ile sınırlıdır. Diğer iş parçacıkları örneklenmemiştir ve raporda görünmeyecektir.
print([io::IO = stdout,] data::Vector, lidict::LineInfoDict; kwargs...)
Profiling sonuçlarını io
'ya yazdırır. Bu varyant, daha önceki bir retrieve
çağrısı ile dışa aktarılan sonuçları incelemek için kullanılır. Geri izlemelerin data
vektörünü ve satır bilgileri için bir lidict
sözlüğünü sağlayın.
Geçerli anahtar kelime argümanlarının açıklaması için Profile.print([io], data)
'ya bakın.
Profile.init
— Functioninit(; n::Integer, delay::Real)
delay
arasında geri izleme (saniye cinsinden ölçülen) ve her bir iş parçacığı başına saklanabilecek n
talimat işaretçisi sayısını yapılandırın. Her talimat işaretçisi, tek bir kod satırına karşılık gelir; geri izlemeler genellikle uzun bir talimat işaretçisi listesi içerir. Geri izleme başına talimat işaretçileri için 6 boşluk kullanıldığını ve iki NULL son işaretleyicisi saklandığını unutmayın. Mevcut ayarlar, bu işlevi argüman olmadan çağırarak elde edilebilir ve her biri bağımsız olarak anahtar kelimeler kullanılarak veya (n, delay)
sırasıyla ayarlanabilir.
Profile.fetch
— Functionfetch(;include_meta = true) -> data
Profilin geri izleme tamponunun bir kopyasını döndürür. data
içindeki değerlerin yalnızca bu makinede ve mevcut oturumda anlamı olduğunu unutmayın, çünkü bu, JIT derlemesinde kullanılan tam bellek adreslerine bağlıdır. Bu işlev esasen dahili kullanım içindir; çoğu kullanıcı için retrieve
daha iyi bir seçim olabilir. Varsayılan olarak, threadid ve taskid gibi meta veriler dahildir. Meta verileri kaldırmak için include_meta
'yı false
olarak ayarlayın.
Profile.retrieve
— Functionretrieve(; kwargs...) -> data, lidict
"Exports" profil sonuçlarını taşınabilir bir formatta döndürür, tüm geri izleme kümesini (data
) ve data
içindeki (oturum-spesifik) talimat işaretçilerini LineInfo
değerlerine eşleyen bir sözlük döndürür; bu değerler dosya adı, fonksiyon adı ve satır numarasını saklar. Bu fonksiyon, profil sonuçlarını gelecekteki analizler için kaydetmenizi sağlar.
Profile.callers
— Functioncallers(funcname, [data, lidict], [filename=<filename>], [linerange=<start:stop>]) -> Vector{Tuple{count, lineinfo}}
Önceki bir profil çalışmasından, belirli bir fonksiyonu kimin çağırdığını belirleyin. Dosya adını (ve isteğe bağlı olarak, fonksiyonun tanımlandığı satır numaraları aralığını) sağlamak, aşırı yüklenmiş bir yöntemi ayırt etmenizi sağlar. Döndürülen değer, çağrı sayısını ve çağıranın satır bilgilerini içeren bir vektördür. İsteğe bağlı olarak, retrieve
ile elde edilen geri izleme data
sağlanabilir; aksi takdirde, mevcut iç profil tamponu kullanılır.
Profile.clear_malloc_data
— Functionclear_malloc_data()
--track-allocation
ile julia çalıştırırken saklanan herhangi bir bellek tahsis verisini temizler. Test etmek istediğiniz komut(lar)ı çalıştırın (JIT derlemesini zorlamak için), ardından clear_malloc_data
çağrısını yapın. Ardından komut(lar)ınızı tekrar çalıştırın, Julia'dan çıkın ve ortaya çıkan *.mem
dosyalarını inceleyin.
Profile.get_peek_duration
— Functionget_peek_duration()
SIGINFO
veya SIGUSR1
aracılığıyla tetiklenen "peek" profilinin süresini saniye cinsinden alır, platforma bağlı olarak.
Profile.set_peek_duration
— Functionset_peek_duration(t::Float64)
SIGINFO
veya SIGUSR1
'e bağlı olarak, platforma göre tetiklenen "peek" profilinin süresini saniye cinsinden ayarlayın.
Memory profiling
Profile.Allocs.@profile
— MacroProfile.Allocs.@profile [örnek_oranı=0.1] expr
expr
sırasında gerçekleşen profil tahsisatlarını profil alır, hem sonucu hem de AllocResults yapısını döndürür.
1.0'lık bir örnek oranı her şeyi kaydedecektir; 0.0 hiçbir şeyi kaydetmeyecektir.
julia> Profile.Allocs.@profile örnek_oranı=0.01 peakflops()
1.03733270279065e11
julia> sonuçlar = Profile.Allocs.fetch()
julia> last(sort(sonuçlar.allocs, by=x->x.size))
Profile.Allocs.Alloc(Vector{Any}, Base.StackTraces.StackFrame[_new_array_ at array.c:127, ...], 5576)
Daha fazla bilgi için Julia belgelerindeki profil alma kılavuzuna bakın.
Daha eski Julia sürümleri tüm durumlarda türleri yakalayamazdı. Daha eski Julia sürümlerinde, Profile.Allocs.UnknownType
türünde bir tahsisat görüyorsanız, bu, profilcinin tahsis edilen nesnenin türünü bilmediği anlamına gelir. Bu, esasen tahsisatın derleyici tarafından üretilen oluşturulmuş koddan geldiği durumlarda meydana geldi. Daha fazla bilgi için sorun #43688 sayfasına bakın.
Julia 1.11'den itibaren, tüm tahsisatların bir türü bildirilmelidir.
Tahsisat profilcisi Julia 1.8'de eklendi.
Profile.Allocs
içindeki yöntemler dışa aktarılmamıştır ve Profile.Allocs.fetch()
gibi çağrılması gerekmektedir.
Profile.Allocs.clear
— FunctionProfile.Allocs.clear()
Önceden profillenen tüm tahsis bilgilerini bellekten temizler.
Profile.Allocs.print
— FunctionProfile.Allocs.print([io::IO = stdout,] [data::AllocResults = fetch()]; kwargs...)
Profiling sonuçlarını io
'ya (varsayılan olarak, stdout
) yazdırır. Eğer bir data
vektörü sağlamazsanız, birikmiş geri izlerin içsel tamponu kullanılacaktır.
Geçerli anahtar kelime argümanlarının açıklaması için Profile.print
'e bakın.
Profile.Allocs.fetch
— FunctionProfile.Allocs.fetch()
Kaydedilen tahsisatları alır ve bunları analiz edilebilecek Julia nesnelerine çözer.
Profile.Allocs.start
— FunctionProfile.Allocs.start(sample_rate::Gerçek)
Verilen örnek oranı ile tahsisatları kaydetmeye başlayın. 1.0'lık bir örnek oranı her şeyi kaydedecek; 0.0 hiçbir şeyi kaydetmeyecek.
Profile.Allocs.stop
— FunctionProfile.Allocs.stop()
Ayrıntıları kaydetmeyi durdur.
Heap Snapshots
Profile.take_heap_snapshot
— FunctionProfile.take_heap_snapshot(filepath::String, all_one::Bool=false, streaming=false)
Profile.take_heap_snapshot(all_one::Bool=false; dir::String, streaming=false)
Yığın anlık görüntüsünü, Chrome Devtools Yığın Anlık Görüntüleyici tarafından beklenen JSON formatında (.heapsnapshot uzantısı) bir dosyaya ($pid_$timestamp.heapsnapshot
) varsayılan olarak geçerli dizine (veya geçerli dizin yazılabilir değilse tempdir'e) yazın, veya verilen dir
'e, veya verilen tam dosya yoluna, veya IO akışına.
Eğer all_one
true ise, o zaman her nesnenin boyutunu bir olarak rapor edin, böylece kolayca sayılabilirler. Aksi takdirde, gerçek boyutu rapor edin.
Eğer streaming
true ise, anlık görüntü verilerini dört dosyaya akıtarak, filepath'ı ön ek olarak kullanarak, tüm anlık görüntüyü bellekte tutmak zorunda kalmamak için bu seçeneği kullanacağız. Bu dosyalar daha sonra Profile.HeapSnapshot.assemble_snapshot()
çağrılarak birleştirilebilir, bu işlem çevrimdışı yapılabilir.
NOT: Performans nedenleriyle streaming=true
ayarını yapmanızı şiddetle tavsiye ederiz. Parçaları birleştirerek anlık görüntüyü yeniden oluşturmak, tüm anlık görüntüyü bellekte tutmayı gerektirir, bu nedenle anlık görüntü büyükse, işlenirken belleğiniz tükenebilir. Akış, anlık görüntüyü çevrimdışı olarak, iş yükünüz çalışmayı bitirdikten sonra yeniden oluşturmanıza olanak tanır. Eğer streaming=false
(geriye dönük uyumluluk için varsayılan) ile bir anlık görüntü toplamaya çalışırsanız ve işleminiz sonlandırılırsa, bu her zaman sağladığınız dosya yoluyla aynı dizine parçaları kaydedecektir, böylece assemble_snapshot()
aracılığıyla sonradan anlık görüntüyü yeniden oluşturabilirsiniz.
Profile
içindeki yöntemler dışa aktarılmamıştır ve Profile.take_heap_snapshot()
gibi çağrılmalıdır.
julia> using Profile
julia> Profile.take_heap_snapshot("snapshot.heapsnapshot")
Yığın üzerindeki julia nesnelerini izler ve kaydeder. Bu yalnızca Julia çöp toplayıcısı tarafından bilinen nesneleri kaydeder. Çöp toplayıcı tarafından yönetilmeyen dış kütüphaneler tarafından tahsis edilen bellek anlık görüntüde görünmeyecektir.
Yığın anlık görüntüsünü kaydederken OOM hatasından kaçınmak için, yığın anlık görüntüsünü dört dosyaya akıtarak akış seçeneği ekledik,
julia> using Profile
julia> Profile.take_heap_snapshot("snapshot"; streaming=true)
"snapshot" dosyası, oluşturulan dosyalar için ön ek olarak kullanılır.
Oluşturulan anlık görüntü dosyaları, aşağıdaki komutla çevrimdışı olarak birleştirilebilir:
julia> using Profile
julia> Profile.HeapSnapshot.assemble_snapshot("snapshot", "snapshot.heapsnapshot")
Oluşan yığın anlık görüntü dosyası, görüntülenmek üzere chrome geliştirici araçlarına yüklenebilir. Daha fazla bilgi için chrome devtools docs adresine bakın. Chromium yığın anlık görüntülerini analiz etmek için bir alternatif, VS Code uzantısı ms-vscode.vscode-js-profile-flame
dir.
Firefox yığın anlık görüntüleri farklı bir formattadır ve Firefox şu anda Julia tarafından üretilen yığın anlık görüntülerini görüntülemek için kullanılamaz.