Profil kode CFD dengan Callgrind

16

Saya menggunakan Valgrind + Callgrind ke profil pemecah yang saya tulis. Seperti yang dinyatakan oleh manual pengguna Valgrind, saya telah mengkompilasi kode saya dengan opsi debugging untuk kompiler:

"Tanpa info debug, alat Valgrind terbaik yang dapat Anda lakukan adalah menebak fungsi kode mana yang menjadi miliknya, yang membuat pesan kesalahan dan keluaran profil hampir tidak berguna. Dengan -g, Anda akan mendapatkan pesan yang mengarah langsung ke baris kode sumber yang relevan. "

Manual Valgrind

Ketika dikompilasi dengan opsi debug, kode berjalan jauh lebih lambat. Kode CFD, menjadi BENAR-BENAR lambat, bahkan untuk kasus-kasus kecil ketika dikompilasi dengan flag debugging. Valgrind membuatnya lebih lambat 40x (lihat manual 1 ).

  1. Alat apa yang Anda gunakan untuk profiling kode (profiling, bukan benchmarking)?

  2. Berapa lama Anda membiarkan kode berjalan (statistik: berapa langkah waktu)?

  3. Seberapa besar kasing (jika kasing masuk ke dalam cache, solver adalah urutan besarnya lebih cepat, tetapi kemudian saya akan kehilangan proses terkait memori)?

tmaric
sumber
3
Anda dapat mengkompilasi kode dengan simbol debug dan optimasi yang diaktifkan. Namun, 40x melalui valgrind (yang mensimulasikan semua akses memori) tidak masuk akal.
Aron Ahmadia
Terima kasih, ini adalah apa yang saya baca juga ... apa yang ingin saya ketahui adalah info tentang pengalaman sehari-hari dalam pembuatan profil (dengan valgrind lebih disukai): berapa banyak waktu yang normal untuk menunggu laporan, berapa banyak iterasi jumlah yang saya butuhkan, apa yang bisa saya kecualikan ... dll ...
tmaric
Pertanyaan Anda juga agak luas. Saya sarankan untuk mengedit pertanyaan Anda agar fokus pada Q2.1 dan Q2.2, karena Q1 adalah pertanyaan yang sama sekali berbeda (saya senang Anda menanyakannya secara terpisah, ini pertanyaan yang bagus, tetapi frasa sebagai "Alat mana yang akan Anda gunakan?" gunakan untuk memecahkan masalah X ", di mana X dijelaskan dengan baik!), sedangkan Q2 sendiri terlalu umum.
Aron Ahmadia
Dapatkah Anda juga mengedit nama callgrind, cachegrindatau massif. Banyak orang mengaitkan Valgrind hanya dengan alat default ( memcheck). Sebagai sistem profiling berbasis emulasi (daripada interrupt-based), Anda tidak perlu menjalankannya untuk waktu yang lama.
Jed Brown
@Ron & Jed: terima kasih atas tipsnya, saya sudah mengedit pertanyaannya. :)
tmaric

Jawaban:

11

T1: Alat apa yang Anda gunakan untuk profiling kode (profiling, bukan benchmarking)?

T2: Berapa lama Anda membiarkan kode berjalan (statistik: berapa langkah waktu)?

T3: Seberapa besar kasing (jika kasing masuk ke dalam cache, solver adalah urutan besarnya lebih cepat, tetapi kemudian saya akan melewatkan proses terkait memori)?

Inilah contoh bagaimana saya melakukannya.

Saya memisahkan pembandingan (melihat berapa lama) dari profil (mengidentifikasi cara membuatnya lebih cepat). Tidaklah penting bahwa profiler menjadi cepat. Penting untuk memberi tahu Anda apa yang harus diperbaiki.

Saya bahkan tidak suka kata "profil" karena memunculkan gambar seperti histogram, di mana ada bilah biaya untuk setiap rutin, atau "bottleneck" karena itu menyiratkan hanya ada sedikit tempat dalam kode yang perlu tetap. Kedua hal ini menyiratkan semacam waktu dan statistik, yang Anda anggap akurasi adalah penting. Tidak ada gunanya memberikan wawasan untuk ketepatan waktu.

Metode yang saya gunakan adalah jeda acak, dan ada studi kasus lengkap dan peragaan slide di sini . Bagian dari pandangan dunia profiler-bottleneck adalah bahwa jika Anda tidak menemukan apa-apa, tidak ada yang ditemukan, dan jika Anda menemukan sesuatu dan mendapatkan persen percepatan tertentu, Anda menyatakan kemenangan dan berhenti. Penggemar profiler hampir tidak pernah mengatakan berapa banyak peningkatan yang mereka dapatkan, dan iklan hanya menampilkan masalah yang dibuat secara artifisial yang dirancang agar mudah ditemukan. Jeda acak menemukan masalah apakah itu mudah atau sulit. Kemudian memperbaiki satu masalah memperlihatkan yang lain, sehingga proses dapat diulang, untuk mendapatkan percepatan yang diperparah.

Dalam pengalaman saya dari banyak contoh, begini caranya: Saya dapat menemukan satu masalah (dengan jeda acak) dan memperbaikinya, mendapatkan percepatan beberapa persen, katakanlah 30% atau 1,3x. Maka saya bisa melakukannya lagi, menemukan masalah lain dan memperbaikinya, mendapatkan speedup lain, mungkin kurang dari 30%, mungkin lebih. Maka saya bisa melakukannya lagi, beberapa kali sampai saya benar-benar tidak dapat menemukan hal lain untuk diperbaiki. Faktor percepatan utama adalah produk yang berjalan dari faktor-faktor individual, dan itu bisa luar biasa besar - pesanan besarnya dalam beberapa kasus.

TERMASUK: Hanya untuk menggambarkan poin terakhir ini. Ada contoh terperinci di sini , dengan tampilan slide dan semua file, yang menunjukkan bagaimana speedup 730x dicapai dalam serangkaian pemindahan masalah. Versi pertama mengambil 2700 mikrodetik per unit kerja. Masalah A telah dihapus, membawa waktu ke 1800, dan memperbesar persentase masalah yang tersisa sebesar 1,5x (2700/1800). Kemudian B dihapus. Proses ini berlanjut melalui enam iterasi, menghasilkan hampir 3 perintah percepatan magnitudo. Tetapi teknik pembuatan profil harus benar-benar manjur, karena jika salah satu dari masalah itu tidak ditemukan, yaitu jika Anda mencapai titik di mana Anda salah berpikir tidak ada lagi yang bisa dilakukan, proses terhenti.

Deskripsi menghapus beberapa masalah untuk mendapatkan speedup besar

DITERBITKAN: Dengan kata lain, inilah grafik dari total faktor percepatan saat masalah yang berurutan dihapus:

masukkan deskripsi gambar di sini

Jadi untuk Q1, untuk benchmarking, timer sederhana sudah cukup. Untuk "profiling", saya menggunakan penghentian sementara.

T2: Saya memberikannya beban kerja yang cukup (atau hanya memutarnya) sehingga berjalan cukup lama untuk berhenti.

T3: Dengan segala cara, berikan itu beban kerja yang sangat besar sehingga Anda tidak ketinggalan masalah cache. Itu akan muncul sebagai sampel dalam kode melakukan pengambilan memori.

Mike Dunlavey
sumber
Mike, apakah Anda memiliki preferensi untuk bagaimana melakukan jeda acak tanpa adanya IDE visual? Bisakah proses ini diotomatisasi dengan cara tertentu?
Matthew Emmett
@ Matthew: Saya mengerti ada alat seperti pstackdan lsstack, tapi saya benar-benar menganggap ini proses yang lebih umum dengan debugging. Jadi, bahkan jika debugger terbaik yang bisa saya bawa adalah gdb, itu menyelesaikan pekerjaan. Dengan debugger Anda dapat memeriksa data, dan itu bisa membuat perbedaan ketika tumpukan itu sendiri tidak memberi tahu Anda cukup.
Mike Dunlavey
9

The profiler miskin manusia pada dasarnya adalah sebuah gdbscript yang sampel panggilan stack. Anda masih harus memiliki simbol debugging. Ini masih lambat, tetapi karena tidak menerapkan mesin virtual untuk menjalankan kode di atasnya seringkali lebih cepat daripada callgrinddan cukup untuk tugas tersebut.

Saya telah menjalankan analisis fisika partikel dengan sedikit keberhasilan (yaitu saya menunjukkan bahwa kode tidak ada hot spot yang mengerikan dan optimasi akan memerlukan algoritma yang lebih baik).

dmckee
sumber
1
+ Tidak adanya bukti bukanlah bukti ketidakhadiran :) Apa yang harus dilakukan oleh profiler orang miskin itu adalah mengambil jejak yang lebih sedikit dan tidak menghancurkannya, tetapi membiarkan Anda melihatnya. Mata manusia jauh lebih baik dalam mendeteksi pola yang berguna daripada perkiraan waktu fungsi yang sederhana, dan jika Anda melihat sesuatu yang dapat Anda perbaiki hanya 2 sampel, itu akan sangat membantu. Fraksi X yang akan disimpan adalah distribusi beta dengan mode 2 / N, di mana N adalah berapa banyak jejak yang Anda periksa, dan faktor speedup akan menjadi 1 / (1-X), yang bisa jadi besar.
Mike Dunlavey
2

Untuk menambah jawaban hebat yang tersedia, ada alat yang dikembangkan di Rice yang mengotomatiskan stack sampling dan karenanya memiliki sedikit overhead:

http://hpctoolkit.org/

Reid.Atcheson
sumber
Itu terlihat bagus, meskipun (maaf) saya sudah memakai topi api saya di sini. Saya tidak mendengarkan kode yang dioptimalkan kompiler karena sulit untuk melihat apa yang terjadi dalam kode yang rusak. Hal-hal yang saya pangkas bukanlah hal-hal yang dapat ditangani oleh optimizer - seperti menelepon expdan logdengan argumen yang sama berulang kali, atau operasi matriks menghabiskan semua waktu mereka mendekode opsi. Saya menyetel sejauh yang saya bisa, kemudian nyalakan -O3.
Mike Dunlavey
Alat adalah alat, dan hanya berguna jika pengguna tahu dan memahami keterbatasannya. Saya tidak berpikir akan pernah ada "profiler sempurna" yang akan menghapus pengguna dari persamaan sama sekali sehubungan dengan memahami outputnya dan mengetahui cara menggunakan informasi tersebut.
Reid.Atcheson
1

Allinea MAP adalah profiler pengambilan sampel yang dikembangkan secara komersial dan didukung dan karenanya - seperti HPC Toolkit yang disarankan dalam jawaban sebelumnya - dapat berjalan pada pekerjaan berukuran produksi jika diinginkan.

Jenis alat ini menunjuk pada kemacetan CPU atau komunikasi MPI yang buruk, tetapi juga seluruh pengawasan pembuatan profil seluruh pekerjaan dapat sangat berharga dalam menemukan masalah yang mengejutkan.

Seringkali ada buah kinerja rendah tergantung yang ada di luar inti kernel dari kode CFD, di daerah yang tidak diharapkan. Pengambilan sampel secara acak adalah - apakah dilakukan secara manual dengan GDB, atau dengan alat-alat seperti HPC Toolkit dan Allinea MAP - cara terbaik untuk menemukannya. Jika ada sesuatu yang penting untuk kinerja itu akan muncul.

David
sumber