Gunakan Sample Profile Guided Optimization (SPGO) untuk meningkatkan performa C++

Profile-Guided Optimization (PGO) menggunakan data runtime untuk membantu kompilator membuat keputusan pengoptimalan yang lebih baik. Dengan menggunakan data profil eksekusi yang dikumpulkan dari beban kerja perwakilan, PGO memungkinkan kompilator membuat keputusan yang lebih cerdas tentang inlining, tata letak kode, dan pemisahan kode panas/dingin. Keputusan ini tidak mungkin dibuat dari analisis statis saja.

SPGO mengambil pendekatan yang berbeda. Alih-alih menyisipkan instrumentasi ke dalam biner Anda dan menjalankannya dalam skenario pelatihan sintetis, SPGO menggunakan sampel penghitung kinerja perangkat keras yang dikumpulkan dari biner rilis aktual Anda. Prosesor modern menyediakan kemampuan pengambilan sampel perangkat keras. Anda dapat mengumpulkan sampel ini dengan overhead runtime yang dapat diabaikan, sehingga pengumpulan profil runtime langsung dari kode produksi menjadi praktis.

Karena profil SPGO merilis bit alih-alih build berinstrumentasi, itu memungkinkan lebih banyak fleksibilitas di mana dan bagaimana Anda mengumpulkan data. Anda dapat mengumpulkan profil runtime dari server produksi, komputer pengembang, lab performa, atau kombinasi apa pun. Hasilnya adalah berkas biner yang menjalankan bagian kode yang paling sering dieksekusi dengan lebih efisien, dengan peningkatan kinerja sebesar 5–15% bergantung pada kualitas data profil.

Untuk informasi selengkapnya tentang Sample Profile-Guided Optimization (PGO) di MSVC dan cara meningkatkan performa menggunakan pembuatan profil berbasis pengambilan sampel, lihat Memperkenalkan Pengoptimalan Terpandu Profil Sampel di MSVC

Dalam tutorial ini, Anda menelusuri alur kerja SPGO lengkap: membuat aplikasi sampel, memprofilkannya dengan menggunakan xperf, menyiapkan data profil, dan membangun kembali dengan data profil. Setelah selesai, Anda dapat menerapkan proses yang sama ke proyek Anda sendiri.

Prasyarat

Sebelum memulai, pastikan Anda memiliki perangkat lunak dan perangkat keras berikut.

Software

  • Alat build MSVC untuk x64/x86/ARM64 versi 14.51 atau yang lebih baru—Instal melalui Visual Studio Installer. Di bawah Komponen Individual, cari "alat bantu build MSVC."
  • Toolkit Performa Windows (xperf.exe)—Profiler xperf mengumpulkan data sampel selama eksekusi program Anda. Unduh Windows Assessment and Deployment Kit (ADK) dari ADK install. Saat Anda menjalankan penginstal ADK, pilih komponen Toolkit Performa Windows untuk mendapatkan xperf. Anda tidak perlu menginstal ADK lengkap.
  • File teks Perang dan Perdamaian—Digunakan sebagai beban kerja sampel untuk menghasilkan data pembuatan profil. Unduh dari Project Gutenberg: https://www.gutenberg.org/ebooks/2600. Simpan sebagai file teks biasa di direktori kerja Anda.

Persyaratan perangkat keras

Tutorial ini memiliki tiga jalur pembuatan profil. Jalur mana yang Anda gunakan tergantung pada perangkat keras Anda. Anda menjalankan perintah deteksi di Pilih metode pembuatan profil Anda untuk mengetahui jalur mana yang didukung komputer Anda. Untuk saat ini, gunakan tabel ini untuk mengonfirmasi bahwa Anda memenuhi setidaknya salah satu persyaratan.

Path Persyaratan CPU Catatan
LBR (hasil terbaik) Last Branch Records (LBR) adalah penghitung kinerja yang disediakan pada CPU Intel Haswell (Core generasi ke-4, 2013) atau yang lebih baru; AMD Zen 4 (2022) atau yang lebih baru, ARM64 ARMv9.2-A (2020) atau yang lebih baru Menyediakan data cabang terbaik. Untuk informasi selengkapnya tentang LBR, lihat Pengantar catatan cabang terakhir
mode PMC/IP (hasil baik) Penghitung Pemantauan Performa (PMC) didukung pada CPU x64 apa pun dengan unit pemantauan performa (PMU) Bekerja pada sebagian besar CPU modern di mana LBR tidak tersedia. Untuk informasi selengkapnya tentang PMC, lihat Merekam Peristiwa Performa Perangkat Keras (PMU) dan Merekam Peristiwa Performa Perangkat Keras (PMU) dengan Contoh Lengkap
Timer OS (berfungsi di mana-mana) CPU x64 atau ARM64 apa pun, termasuk VM Azure dan komputer virtual Sampel keakuratan yang lebih rendah, tetapi selalu tersedia

Sebagian besar pengembang pada perangkat keras desktop x64 modern memiliki dukungan LBR. VM dan beberapa perangkat keras yang lebih lama memiliki PMC atau timer OS.

Cara kerja SPGO

SPGO mengumpulkan data profil dari biner yang sedang berjalan dan mengirimkannya kembali ke kompilator saat Anda melakukan build berikutnya. Pengkompilasi menggunakan data tersebut untuk membuat keputusan yang lebih baik tentang inlining, tata letak kode, dan prediksi cabang. Kenyamanan adalah bahwa tidak ada instrumentasi yang diperlukan.

Alur kerjanya adalah:

  1. Kompilasikan biner Anda dengan flag penaut /spgo. Langkah ini membuat database profil sampel kosong (.spd file).
  2. Profil biner dengan menggunakan xperf untuk menghasilkan file pelacakan ETL.
  3. Konversikan ETL ke file SPT dengan menggunakan SPTAggregate.exe, lalu konversikan SPT ke file SPD dengan menggunakan SPDConvert.exe.
  4. Kompilasi ulang dengan flag linker /spdin yang mengarah ke basis data profil sampel (SPD) yang telah diisi. Linker menerapkan pengoptimalan SPGO.

Pengoptimal menggunakan SPD untuk menjawab pertanyaan seperti: cabang mana yang paling sering diambil? Fungsi mana yang disebut dalam perulangan panas? Proses ini menghasilkan tata letak kode yang lebih baik dan keputusan terkait inlining yang lebih baik daripada analisis statis saja.

SPGO berfungsi dengan C dan C++. Alur kerja dan bendera identik untuk kedua bahasa tersebut.

Kandidat terbaik untuk SPGO: Aplikasi C/C++ berukuran besar dengan banyak percabangan dan loop internal yang ketat. Keuntungannya meningkat seiring dengan ukuran basis kode dan kompleksitas branch. Sampel kecil dalam tutorial ini menunjukkan sekitar 7 peningkatan%. Basis kode produksi yang lebih besar sering melihat lebih banyak peningkatan.

Perbandingan Proses Build

Bagian ini menjelaskan bagaimana SPGO terintegrasi dalam alur build jika Anda ingin memahami mekanismenya.

Proses kompilasi normal

Dalam build rilis C/C++ standar:

  • Input: File kode sumber (.cpp, .h) dan bendera pengkompilasi mode rilis (/O2, /GL, dan sebagainya).
  • Proses: Kompilator menerapkan pengoptimalan standar seperti heuristik inlining, asumsi prediksi cabang, dan keputusan tata letak kode berdasarkan analisis statis saja. Ini tidak memiliki data tentang bagaimana program benar-benar berperilaku ketika berjalan.
  • Output: Berkas eksekusi (.exe), berkas DLL (.dll), informasi penelusuran kesalahan (.pdb).

Diagram proses build rilis normal memperlihatkan file kode sumber dan contoh sakelar pengkompilasi /GL saat input mengalir ke langkah build, yang menghasilkan output .exe, .dll, dan .pdb.

Tanpa data runtime, jalur panas dan jalur dingin menerima perlakuan serupa.

Proses build yang didukung SPGO

SPGO menambahkan data pembuatan profil sebagai input baru ke alur build:

  • Masukan: Kode sumber, .spd berkas profil (jumlah sampel dari proses pembuatan profil), flag kompiler mode rilis, /link /spgo, dan /spdin:<path> untuk menentukan berkas SPD masukan (jika tidak ditentukan, secara default akan menggunakan berkas .spd yang memakai nama biner dan berada di folder obj).
  • Proses: Penaut membaca SPD bersamaan dengan kode perantara. Ini menggunakan data frekuensi cabang untuk mengambil keputusan yang lebih baik terkait inlining, tata letak kode, dan pengurutan cabang. Fungsi panas ditata untuk akses cepat; kode dingin bergerak keluar dari jalur kritis.
  • Output: Executable yang dioptimalkan (.exe), file DLL yang dioptimalkan (.dll), informasi debug (.pdb), dan file baru .spd untuk iterasi pembuatan profil di masa mendatang.

Diagram proses build yang mendukung SPGO, yang menunjukkan kode sumber dan file data profil (.spd) sebagai masukan untuk langkah build dengan opsi linker tambahan /spgo. Proses build ini menghasilkan file .exe dan .dll yang dioptimalkan, informasi debug (.pdb), serta file data profil baru (.spd).

Wawasan utama: SPGO memindahkan keputusan pengoptimalan dari kompilator dan heuristik tautan ke pilihan berbasis data berdasarkan eksekusi nyata.

Bendera kunci

Tanda Type Kegunaan
/spgo Linker Mengaktifkan SPGO. Menyematkan metadata SPGO dalam biner dan membuat file output kosong .spd kecuali /spdin ditentukan, dalam hal ini file yang ditentukan .spd digunakan sebagai input.
/spdin:<path> Linker INPUT SPD - menyediakan data profil ke linker untuk pengoptimalan
/spd:<path> Linker Jalur keluaran SPD - menentukan lokasi penulisan SPD baru (opsional; secara bawaan menggunakan direktori yang sama dengan berkas biner). Berfungsi sebagai jalur SPD input jika /spdin tidak ditentukan.
/GL Kompilator Pengoptimalan seluruh program yang diperlukan agar SPGO berfungsi di seluruh unit terjemahan
/O1, /O2 (Minimalkan Ukuran, Maksimalkan Kecepatan) Kompilator Optimalkan untuk kecepatan; memungkinkan pengoptimalan yang agresif yang dapat lebih dioptimalkan oleh SPGO

Bagaimana SPGO berbeda dari PGO

PGO (Profile-Guided Optimization) mengharuskan Anda untuk mengkompilasi biner Anda dengan bendera instrumentasi (/GENPROFILE), menjalankan biner berinstrumen yang lebih lambat untuk mengumpulkan .pgc file jumlah eksekusi, lalu menautkan ulang dengan /USEPROFILE. Kompilator memperoleh jumlah eksekusi yang akurat, tetapi Anda harus menginstrumentasi kode terlebih dahulu. Untuk informasi selengkapnya tentang proses ini, lihat Pengoptimalan yang dipandu profil.

SPGO menggunakan penghitung kinerja CPU perangkat keras untuk mengumpulkan sampel statistik dari biner rilis Anda yang tidak terinstrumentasi. Jalankan biner yang ada, profilkan dengan menggunakan xperf, konversikan jejak ke file SPD, dan bangun ulang. Tidak ada build berinstrumentasi dan tidak ada perlambatan selama pembuatan profil. Pengkompilasi mendapatkan data pengambilan sampel statistik alih-alih jumlah yang tepat, yang kurang tepat tetapi lebih mudah untuk mendapatkan dan tidak memerlukan perubahan kode. Ini juga memungkinkan pembuatan profil komponen sistem atau komponen realtime yang sulit untuk mengumpulkan data dengan pendekatan berinstrumentasi. Anda juga dapat memprofilkan biner akhir/pengiriman.

Tutorial ini mencakup tiga metode pembuatan profil: LBR, PMC, dan timer OS. Anda memilih metode Anda di Memilih metode pembuatan profil Anda. Untuk perbandingan terperinci antara proses build normal dan proses build SPGO, termasuk tabel referensi flag, lihat Perbandingan Proses Build.

Mengkonfigurasi perfcore.ini

⚠️ Diperlukan: Tanpa langkah ini, xperf tidak memberikan data pembuatan profil yang diperlukan. Selesaikan langkah ini sebelum menjalankan xperf.

Toolkit Performa Windows (WPT) menggunakan perfcore.ini, yang terletak jika Anda menginstal WPT di lokasi default di C:\Program Files (x86)\Windows Kits\10\Toolkit Performa Windows\perfcore.ini, untuk mendaftarkan penyedia DLL yang dibutuhkan untuk SPGO.

Buka Windows Notepad sebagai Administrator. Kemudian buka perfcore.ini. Temukan bagian daftar DLL dan tambahkan entri berikut, satu per baris:

perf_lbr.dll
perf_spt.dll
perf_hv.dll

Jika xperf.exe tidak diinstal, lihat Masalah umum untuk menginstalnya.

Simpan dan tutup perfcore.ini. File DLL sudah dikirim ke direktori xperf.exe yang sama sehingga Anda tidak perlu menyalinnya di mana saja. Anda hanya mendaftarkannya di perfcore.ini. Pastikan xperf ada di PATH Anda.

Membuat sampel aplikasi

Aplikasi sampel untuk tutorial ini adalah program C++ yang membaca teks dari input standar dan menghasilkan jumlah baris, jumlah kata, jumlah karakter total, tabel frekuensi karakter, dan waktu yang berlalu untuk memproses file dalam milidetik. Ini ditulis dalam C++, tetapi SPGO juga berfungsi dengan C. Alur kerja identik untuk proyek C.

Buat file bernama textCount.cpp di direktori kerja Anda dan tambahkan kode sumber berikut:

// textCount.cpp : Text Statistics Counter
// Counts words, lines, and character frequencies from standard input
// Usage: textCount < file.txt

#include <iostream>
#include <string>
#include <map>
#include <cctype>
#include <chrono>

int main()
{
    auto start = std::chrono::steady_clock::now();

    std::map<unsigned char, int> charFrequency;
    int wordCount = 0;
    int lineCount = 0;
    int totalChars = 0;

    std::string line;
    bool inWord = false;

    while (std::getline(std::cin, line))
    {
        lineCount++;

        for (char c : line)
        {
            totalChars++;
            unsigned char uc = static_cast<unsigned char>(c);
            charFrequency[uc]++;

            if (std::isspace(static_cast<unsigned char>(c)))
            {
                inWord = false;
            }
            else
            {
                if (!inWord)
                {
                    wordCount++;
                    inWord = true;
                }
            }
        }

        inWord = false;
    }

    std::cout << "\n=== TEXT STATISTICS ===" << std::endl;
    std::cout << "Lines: " << lineCount << std::endl;
    std::cout << "Words: " << wordCount << std::endl;
    std::cout << "Total Characters: " << totalChars << std::endl;

    std::cout << "\n=== CHARACTER FREQUENCIES ===" << std::endl;

    std::cout << "\nLetters:" << std::endl;
    for (unsigned char ch = 'a'; ch <= 'z'; ch++)
    {
        unsigned char upperCh = static_cast<unsigned char>(std::toupper(ch));
        int count = charFrequency[ch] + charFrequency[upperCh];
        if (count > 0)
        {
            std::cout << static_cast<char>(ch) << ": " << count << std::endl;
        }
    }

    std::cout << "\nDigits:" << std::endl;
    for (unsigned char ch = '0'; ch <= '9'; ch++)
    {
        if (charFrequency[ch] > 0)
        {
            std::cout << static_cast<char>(ch) << ": " << charFrequency[ch] << std::endl;
        }
    }

    std::cout << "\nSpecial Characters:" << std::endl;
    for (const auto& pair : charFrequency)
    {
        unsigned char ch = pair.first;
        if (!std::isalnum(ch))
        {
            std::string displayChar;
            switch (ch)
            {
                case ' ': displayChar = "[space]"; break;
                case '\t': displayChar = "[tab]"; break;
                case '\n': displayChar = "[newline]"; break;
                case '\r': displayChar = "[return]"; break;
                default:
                    if (ch >= 32 && ch < 127)
                    {
                        displayChar = std::string(1, static_cast<char>(ch));
                    }
                    else
                    {
                        displayChar = "[byte:" + std::to_string(static_cast<int>(ch)) + "]";
                    }
                    break;
            }
            std::cout << displayChar << ": " << pair.second << std::endl;
        }
    }

    auto end = std::chrono::steady_clock::now();

    auto elapsed = std::chrono::duration<double, std::milli>(end - start);
    std::cout << "Elapsed time: " << std::fixed;
    std::cout.precision(3);
    std::cout << elapsed.count() << " ms\n";

    return 0;
}

Buat dan jalankan sampel untuk mendapatkan dasar acuan

Sebelum menerapkan SPGO, buat textCount dan jalankan terhadap file teks besar, seperti War dan Peace (Anda dapat mengunduhnya dari Project Gutenberg), untuk melihat seberapa cepat eksekusinya. Langkah ini menunjukkan performa sebelum mengoptimalkannya dengan menggunakan SPGO:

Membangun:

cl /Zi /EHsc /GL /O2 textCount.cpp /link /debug

Menjalankan:

textCount.exe < warAndPeace.txt

Anda melihat output yang mirip dengan:

=== TEXT STATISTICS ===
Lines: 66041
Words: 566333
Total Characters: 3227531

=== CHARACTER FREQUENCIES ===

Letters:
a: 202719
...

Elapsed time: 512.000 ms

Catat nilainya Elapsed time . Anda akan membandingkannya dengan waktu yang dioptimalkan SPGO dalam Mengukur hasilnya.

Buat textCount dengan /spgo

Sekarang buat textCount dengan SPGO diaktifkan. Langkah ini meletakkan dasar untuk mengumpulkan data pembuatan profil.

cl /Zi /EHsc /GL /O2 textCount.cpp /link /debug /spgo

Setelah build selesai, Anda akan melihat pesan seperti:

SPD textCount.spd not found, compiling without profile guided optimizations

Pesan ini muncul pada build pertama /spgo . Linker membuat file SPD tetapi masih kosong, sehingga belum menerapkan pengoptimalan SPGO. Setelah menjalankan biner, mengumpulkan data profil, dan mengonversinya menjadi SPD, Anda tidak akan melihat pesan ini.

Penjelasan bendera:

Tanda Kegunaan
/Zi Buat informasi debug lengkap. Ini diperlukan agar SPGO memetakan sampel pembuatan profil ke kode sumber.
/EHsc Mengaktifkan penanganan pengecualian C++
/GL Pengoptimalan seluruh program — diperlukan untuk SPGO. Menunda pengoptimalan akhir hingga tahap penautan, sehingga memungkinkan penyisipan sebaris lintas modul, penataan kode, dan keputusan penghapusan kode mati.
/O2 Optimalkan untuk kecepatan — memungkinkan inlining agresif, pengoptimalan perulangan, penghapusan kode yang tidak digunakan, dan transformasi terkait lainnya.
/link /debug Berikan /debug ke linker untuk menghasilkan informasi debug (.pdb), yang digunakan oleh xperf untuk memetakan sampel profil ke kode sumber.
/spgo Flag linker SPGO—menyematkan metadata SPGO ke dalam biner dan membuat file textCount.spd kosong di samping file executable.

Nota

/spgo adalah bendera linker. Teruskan ke linker melalui /link /spgo dalam perintah cl.

Bendera /spgo belum mengoptimalkan biner. Ini mempersiapkannya untuk pembuatan profil. Pengoptimalan dilakukan di membangun ulang textCount dengan /spdin setelah SPD diisi dengan data runtime aktual.

Nota

Untuk menulis SPD ke lokasi tertentu, tambahkan bendera linker opsional /spd:<path> . Misalnya: /link /debug /spgo /spd:.\profiles\textCount.spd. Jika Anda menghilangkan flag ini, SPD dibuat bersama .exe.

Pilih metode pembuatan profil Anda

SPGO mendukung tiga metode pembuatan profil. Metode mana yang Anda gunakan tergantung pada perangkat keras Anda.

Tiga metode pembuatan profil

Metode Kualitas sampel Persyaratan perangkat keras Paling cocok untuk
LBR (Catatan Cabang Terakhir) Tertinggi—mencatat urutan cabang yang baru diambil, memberikan data aliran kontrol yang kaya kepada pengoptimal per sampel Intel Haswell (2013) atau yang lebih baru; AMD Zen 4 (2022) atau yang lebih baru; ARM64 ARMv9.2-A (2020) atau yang lebih baru Perangkat keras desktop paling modern
Mode PMC / IP (mode Penghitung Pemantauan Kinerja/penunjuk instruksi) Bagus. Menangkap sampel penunjuk instruksi beserta tumpukan panggilan menggunakan Unit Pemantauan Kinerja (PMU) CPU melalui Event Tracing for Windows (ETW) CPU x64 atau ARM64 apa pun dengan PMU Perangkat keras tanpa dukungan LBR
Timer OS Dasar—sampel berbasis pengatur waktu CPU x64 maupun ARM64 apa saja, VM tanpa penerusan PMU VM dan perangkat keras yang lebih lama

Dengan mode PMC / IP, setiap gangguan perangkat keras memberi Anda hanya satu poin data: "CPU berada di alamat 0x1A2B3C4D ketika gangguan diaktifkan". Dengan LBR, setiap interupsi memberikan tumpukan yang berisi 16–32 cabang terakhir yang diambil CPU sebelum interupsi terjadi. Pengoptimal memperoleh data alur kontrol yang lebih baik dan dapat membuat keputusan yang lebih baik terkait inlining dan tata letak.

Deteksi rute Anda

Jalankan dua perintah berikut untuk menentukan jalur pembuatan profil mana yang didukung komputer Anda. Perintah ini tidak memerlukan prompt yang ditingkatkan.

Langkah 1: Periksa dukungan LBR. Pengujian ini berfungsi pada Intel/AMD/ARM64.

Jalankan hal berikut dari perintah pengembang administrator Visual Studio:

xperf.exe -on PMC_PROFILE -pmcprofile TotalIssues -LastBranch PmcInterrupt -setProfInt TotalIssues 2560000
xperf -stop -d lbrtest.etl
xperf -tle -i lbrtest.etl -a dumper | findstr "LBR,  TimeStamp"
  • Jika perintah ini menemukan baris yang berisi LBR, TimeStamp, maka komputer Anda mendukung LBR. Gunakan jalur LBR.
  • Jika tidak, lanjutkan ke Langkah 2.

Langkah 2: Periksa dukungan PMC (tanpa LBR)

xperf.exe -pmcsources | findstr TotalIssues
  • Jika perintah ini menghasilkan output, komputer Anda mendukung penghitung PMC tetapi bukan LBR. Gunakan jalur PMC.
  • Jika perintah ini tidak menghasilkan output, maka Gunakan jalur timer OS.

Untuk informasi selengkapnya tentang pengumpulan peristiwa PMU dengan xperf, lihat Merekam peristiwa PMU perangkat keras dengan xperf.

Tabel keputusan

LBR, TimeStamp keluaran TotalIssues keluaran Jalur Anda
Tidak kosong (tidak diperiksa) LBR
Empty Tidak kosong PMC
Empty Empty Timer sistem operasi
Prosesor ARM64 N/A PMC (jika PMU tersedia) atau timer OS

Pilih pendekatan Anda

Putuskan apakah akan menggunakan jalur timer LBR, PMC, atau OS berdasarkan hasil deteksi. Setiap jalur memiliki parameter mulai yang berbeda xperf untuk mengumpulkan data pembuatan profil yang sesuai. Ikuti jalur yang cocok dengan kemampuan perangkat keras Anda.

Jalur Anda:

  • Pengguna LBR (LBR terdeteksi di Langkah 1): Buka jalur LBR.
  • Pengguna PMC (InstructionRetired terdeteksi di Langkah 2): Akses jalur PMC (tanpa LBR).
  • Pengguna timer OS (VM atau perangkat keras tanpa PMU): Buka jalur timer OS.

Semua jalur bergabung kembali di Jalankan beban kerja dan hentikan xperf.

Perintah di bagian ini bergantung pada jalur pembuatan profil yang Anda identifikasi di Pilih metode pembuatan profil Anda. Temukan subbagian yang cocok dengan jalur Anda, jalankan xperf perintah mulai, lalu lanjutkan menjalankan beban kerja dan hentikan xperf untuk menjalankan beban kerja dan menghentikan xperf.

⚠️ Jalankan sebagai Administrator:xperf memerlukan prompt perintah pengembang (Administrator) yang ditinggikan. Tanpa elevasi, xperf mengembalikan "failed to configure counters".

Jalur LBR

Mulai xperf dengan koleksi LBR:

xperf -on LOADER+PROC_THREAD+PMC_PROFILE -MinBuffers 4096 -MaxBuffers 4096 -BufferSize 4096 -pmcprofile BranchInstructionRetired -LastBranch PmcInterrupt -setProfInt BranchInstructionRetired 16384

Penjelasan parameter:

Parameter Kegunaan
LOADER+PROC_THREAD+PMC_PROFILE Penyedia kernel: peristiwa pemuat (pemetaan modul), peristiwa proses/utas (konteks eksekusi), dan peristiwa pembuatan profil PMC
-MinBuffers 4096 -MaxBuffers 4096 -BufferSize 4096 Buffer cincin besar untuk menghindari hilangnya sampel selama proses penuh War and Peace
-pmcprofile BranchInstructionRetired Pemicu peristiwa PMC: menghasilkan sampel pada setiap instruksi percabangan ke-N yang telah dipensiunkan
-LastBranch PmcInterrupt Mengaktifkan perekaman perangkat keras LBR: pada setiap interupsi PMC, tangkap tumpukan rekaman cabang terakhir pada perangkat keras
-setProfInt BranchInstructionRetired 16384 Interval pengambilan sampel: picu interupsi setiap 16.384 instruksi percabangan yang telah selesai dieksekusi

Setelah memulai xperf, lanjutkan untuk Menjalankan beban kerja dan menghentikan xperf.

Jalur PMC (tanpa LBR)

Mulailah xperf dengan koleksi mode PMC / IP:

xperf -on LOADER+PROC_THREAD+PMC_PROFILE+PROFILE -MinBuffers 4096 -BufferSize 4096 -pmcprofile InstructionRetired -setProfInt InstructionRetired 16384 -stackwalk profile

Penjelasan parameter:

Parameter Kegunaan
LOADER+PROC_THREAD+PMC_PROFILE+PROFILE Menambahkan PROFILE (pengambilan sampel CPU) dan PMC_PROFILE untuk peristiwa PMC; tidak ada -LastBranch
-pmcprofile InstructionRetired Pemicu peristiwa PMC: sampel pada instruksi yang dihentikan (mode penunjuk instruksi)
-setProfInt InstructionRetired 16384 Aktifkan interupsi setiap 16.384 instruksi yang dihentikan
-stackwalk profile Ambil tumpukan panggilan pada setiap interupsi profil, menyediakan data rantai panggilan alih-alih urutan cabang

Dibandingkan dengan LBR: tidak ada flag -LastBranch; menggunakan InstructionRetired alih-alih BranchInstructionRetired. Hasilnya adalah sampel penunjuk instruksi dengan tumpukan panggilan, bukan urutan cabang. Jalur ini masih menyediakan data yang efektif bagi pengoptimal, tetapi datanya sedikit kurang kaya.

Setelah memulai xperf, lanjutkan untuk Menjalankan beban kerja dan menghentikan xperf.

jalur timer OS

Mulai xperf dengan pengambilan sampel berbasis timer OS:

xperf -on LOADER+PROC_THREAD+PROFILE -MinBuffers 4096 -BufferSize 4096 -setProfInt Timer 1221 -stackwalk profile

Penjelasan parameter:

Parameter Kegunaan
LOADER+PROC_THREAD+PROFILE Tidak ada peristiwa PMC; Pengambilan sampel CPU melalui interupsi timer OS saja
-setProfInt Timer 1221 Kebakaran pada timer OS mengganggu setiap 1.221 kutu timer (sekitar 1 kHz)
-stackwalk profile Menangkap tumpukan panggilan pada setiap interupsi timer

Dibandingkan dengan LBR dan PMC, metode ini tidak menggunakan penghitung kinerja perangkat keras. Timer OS terpicu pada interval waktu yang relatif tetap, terlepas dari aktivitas CPU. Sampel memiliki korelasi yang tidak sepadat dengan kode yang sering dieksekusi, tetapi masih menyediakan data alur kontrol yang berguna bagi pengoptimal.

Jalankan beban kerja dan hentikan xperf (semua jalur)

Dengan xperf menjalankan, lari textCount melawan Perang dan Perdamaian:

textCount.exe < warAndPeace.txt

Setelah textCount selesai, hentikan xperf dan tulis file pelacakan. Membiarkan proses lain berjalan selama pembuatan profil mencairkan kualitas sampel. Untuk hasil terbaik, tutup aplikasi yang tidak perlu sebelum menjalankan beban kerja.

xperf -stop -d textCount.etl

Setelah menghentikan xperf (mungkin perlu beberapa saat untuk menuliskan file etl), pastikan bahwa textCount.etl telah dibuat di direktori saat ini.

Mengonversi file ETL ke SPT

Langkah ini sama untuk ketiga jalur pembuatan profil.

Jalankan SPTAggregate.exe untuk memproses jejak ETL mentah dan buat file profil SPT:

SPTAggregate.exe /binary textCount.exe /etl textCount.etl textCount.spt

Penjelasan parameter:

Parameter Kegunaan
/binary textCount.exe Biner untuk mengekstrak sampel dari. ETL mungkin berisi sampel dari semua proses yang berjalan selama pembuatan profil
/etl textCount.etl Input file pelacakan ETL
textCount.spt File profil keluaran SPT

SPTAggregate menghasilkan ringkasan yang menunjukkan berapa banyak sampel yang dikumpulkannya. Ringkasan ini adalah konfirmasi pertama Anda bahwa pembuatan profil berfungsi.

Cocokkan output dari SPTAggregate dengan jalur yang Anda ambil:

  • Jalur LBR: Cari jumlah Sampel LBR yang Digunakan yang bukan nol.
  • Jalur PMC: Cari PMC yang bukan nol atau jumlah sampel stack.
  • Jalur timer OS: Cari jumlah sampel stack yang digunakan yang bukan nol.

Jika semua jumlah adalah nol, lihat Pemecahan masalah sebelum melanjutkan.

Mengonversi file SPT ke SPD

Jalur Anda:

Baik jalur timer PMC maupun OS menggunakan /mode:IP karena keduanya menghasilkan sampel pointer instruksi.

Langkah berikutnya bercabang berdasarkan jalur pembuatan profil, khususnya pada flag /mode yang diteruskan ke SPDConvert.exe.

Mode LBR

SPDConvert.exe /mode:LBR textCount.spd textCount.spt

/mode:LBR memberi tahu SPDConvert agar menafsirkan SPT sebagai memuat data urutan percabangan LBR.

Mode IP (PMC dan timer OS)

Baik timer PMC maupun timer OS menghasilkan sampel penunjuk instruksi, sehingga keduanya menggunakan perintah konversi yang sama:

SPDConvert.exe /mode:IP textCount.spd textCount.spt

/mode:IP memberi tahu SPDConvert untuk menafsirkan SPT sebagai yang berisi sampel penunjuk instruksi.

Warning

Menggunakan mode yang salah untuk jenis data Anda dapat menghasilkan SPD kosong atau salah bentuk. Jika Anda membuat profil dengan LBR, gunakan /mode:LBR. Jika Anda melakukan profiling dengan PMC atau pewaktu OS, gunakan /mode:IP. Output ringkasan SPTAggregate dari Konversikan file ETL ke SPT menunjukkan jenis sampel yang dikumpulkan dan mengonfirmasi mode yang tepat untuk digunakan.

Setelah menjalankan SPDConvert, konfirmasikan bahwa textCount.spd telah dibuat (atau diperbarui) di direktori saat ini.

Menafsirkan keluaran SPDConvert

Perintah SPDConvert textCount.spd textCount.spt mencetak ringkasan cakupan blok sebelum dan sesudahnya, misalnya:

Block coverage (before) : 33.90% ( 4507/ 13294)
Block coverage (after)  : 45.64% ( 6067/ 13294)

Ringkasan ini menunjukkan persentase blok kode biner yang memiliki data profil terkait. Persentase yang lebih tinggi lebih baik. Cakupan di atas 70% sangat baik, sementara cakupan di bawah 40% mungkin membatasi efektivitas pengoptimalan. Jika cakupan rendah, jalankan beban kerja pembuatan profil lebih lama atau gabungkan beberapa file SPT dari eksekusi terpisah dengan beban kerja yang berbeda. Misalnya, Anda dapat menjalankan textCount pada beberapa file teks untuk menguji jalur kode yang berbeda.

Anda mungkin melihat peringatan dari SPDConvert seperti berikut ini:

Compiler may be conservative on some hot functions due to sparse sample coverage.
SPGO is estimated to optimize better if sample density is increased to 5.4x of current level.
Sample density can be increased by sampling for longer period, or increasing sample rate.

Peringatan ini berarti proses profiling Anda tidak mengumpulkan cukup sampel agar pengoptimal dapat mengoptimalkan semua fungsi yang sering dipanggil secara meyakinkan. SPD masih dapat digunakan, tetapi Anda dapat meningkatkan hasil dengan:

  • Menjalankan beban kerja lebih lama (misalnya, 5 menit atau lebih, bukan 1 menit) atau menggunakan beban kerja yang berbeda.
  • Menurunkan -setProfInt nilai dalam xperf perintah untuk meningkatkan laju pengambilan sampel. Tradeoff adalah bahwa perubahan ini menghasilkan file ETL yang lebih besar, yang membutuhkan waktu lebih lama untuk diproses.
  • Menggabungkan beberapa file SPT dari proses pembuatan profil terpisah dengan meneruskannya semuanya ke SPDConvert.

File SPT adalah format biner. Untuk memeriksa kontennya, Anda dapat menjalankan SPTDump.exe textCount.spt. Demikian pula, PTDump.exe textCount.spt menunjukkan data profil yang dikompilasi setelah menjalankan SPDConvert. Kedua alat berguna untuk memverifikasi sampel nonzero sebelum melanjutkan.

Membangun kembali textCount dengan /spdin

Bangun ulang textCount menggunakan file SPD yang telah diisi. Linker membaca data profil dan menerapkan pengoptimalan SPGO.

Langkah ini sama untuk ketiga jalur pembuatan profil.

cl /Zi /EHsc /GL /O2 textCount.cpp /link /debug /spgo /spdin:textCount.spd

Flag baru (dibandingkan dengan Build textCount dengan /spgo):

Tanda Kegunaan
/spdin:textCount.spd Berikan data profil SPD ke linker untuk pengoptimalan

Perintah masih mencakup /spgo. Ini menghasilkan file SPD baru bersama biner yang dioptimalkan, yang dapat Anda gunakan sebagai titik awal untuk iterasi pembuatan profil berikutnya.

Warning

File SPD terkait dengan biner persis yang menjadi acuan profiling-nya. Jika Anda membangun textCount kembali tanpa /spdin, atau membangun kembali dari sumber yang diubah, Anda harus membuat file SPD baru. Yang sudah ada tidak cocok dengan GUID biner baru, dan linker tidak akan menggunakannya.

Setelah dibangun kembali dengan /spdin, linker menghasilkan statistik tentang berapa banyak kode Anda yang dioptimalkan menggunakan data profil. Contohnya:

221 of 221 (100.00%) profiled functions will be compiled for speed
201 of 1383 inline instances were from dead/cold paths
474 of 474 profiled functions (100.0%) were optimized using profile data
202738780 of 202738780 instructions (100.0%) were optimized using profile data

Persentase tinggi berarti SPD mencakup biner Anda dengan baik. Jika persentase rendah (misalnya, di bawah 90%), beban kerja pembuatan profil tidak cukup menggunakan biner, atau biner telah berubah secara signifikan sejak profil dikumpulkan. Dalam kedua kasus, buat profil ulang menggunakan biner saat ini.

Apa yang dilakukan SPGO dengan data profil Anda

SPGO menggunakan data sampel yang dikumpulkan untuk mengisi jumlah pada setiap blok dan tepi dalam grafik alur kontrol program. Jumlah ini mendorong pengoptimalan seperti:

  • Inlining yang dipandu profil: Secara agresif melakukan inlining pada lokasi pemanggilan yang sering dieksekusi sambil menghindari pembengkakan kode akibat inlining pada jalur yang jarang dieksekusi.
  • Pemisahan kode panas/dingin: Pindahkan kode yang jarang dijalankan untuk memisahkan bagian biner, meningkatkan pemanfaatan cache instruksi dan perilaku halaman.
  • Tata letak fungsi: Tempatkan fungsi yang sering saling memanggil satu sama lain di biner, mengurangi kesalahan halaman dan meningkatkan lokalitas. Fungsi yang dioptimalkan dikelompokkan ke dalam grup COFF berafinitas tinggi di dalam biner.
  • Keputusan ukuran/kecepatan: Kompilasi fungsi panas untuk fungsi kecepatan dan dingin untuk ukuran. Rutinitas yang tidak memiliki akses profil yang teramati mungkin dikompilasi dengan mengutamakan ukuran alih-alih kecepatan, sehingga membatasi pengoptimalan seperti inlining dan penguraian loop pada jalur yang jarang dieksekusi.
  • Devirtualisasi spekulatif: Ketika pengambilan sampel mengungkapkan bahwa panggilan tidak langsung secara konsisten mengarah ke fungsi yang sama, SPGO dapat membuat asumsi tentang target tersebut dan menyisipkannya secara inline, dengan jalur cadangan untuk kasus yang jarang terjadi.

Mengukur hasil

Jalankan textCount lagi dan bandingkan waktu yang berlalu.

textCount.exe < warAndPeace.txt

Kumpulkan beberapa eksekusi untuk setiap konfigurasi dan gunakan median. Satu kali eksekusi tidak dapat diandalkan karena penjadwalan OS dan kebisingan sistem dapat menyimpangkan hasil setiap pengukuran.

Build Waktu berlalu representatif
Garis besar (cl /Zi /EHsc /O2 /link /debug) (pengukuran Anda)
/spgo build (belum ada data profil) (harus dekat dengan garis besar)
Dioptimalkan untuk SPGO (/spdin) (harus menunjukkan peningkatan)

Dalam sebuah pengujian, SPGO yang menggunakan metode LBR menghasilkan penurunan waktu eksekusi sekitar 7%. Hasil Anda mungkin bervariasi dengan proyek Anda sendiri karena keuntungan SPGO bergantung pada seberapa baik beban kerja pembuatan profil mewakili eksekusi umum. Basis kode yang lebih besar dan terisi cabang cenderung melihat lebih banyak peningkatan dalam rentang 5-10%. Metode pembuatan profil memengaruhi kualitas pengoptimalan. LBR biasanya menghasilkan hasil yang lebih baik daripada PMC, yang menghasilkan hasil yang lebih baik daripada timer OS. Jika Anda menggunakan mekanisme timer OS, peningkatan yang diperoleh akan lebih kecil.

Jalur LBR yang diikuti dalam tutorial ini diterapkan ke proyek SQLite , yang merupakan pustaka database produksi. Biner SQLite yang dioptimalkan SPGO menunjukkan peningkatan sekitar 7%.

Terapkan SPGO ke proyek Anda sendiri

Gunakan daftar periksa ini untuk menerapkan SPGO ke aplikasi C atau C++ Anda sendiri.

  1. Tambahkan /Zi /link /debug /spgo ke perintah build rilis yang ada. Ubah skrip build atau file proyek Anda:

    cl /Zi /EHsc /GL /O2 myapp.cpp /link /debug /spgo
    
  2. Pilih beban kerja yang representatif. Pilih skenario penggunaan nyata yang menggunakan jalur eksekusi yang paling sering digunakan dalam aplikasi Anda. Gunakan data yang menyerupai data produksi. Hindari hal berikut sebagai beban kerja pembuatan profil utama Anda: pengujian cakupan kode (tidak menekankan hambatan performa), jalur kesalahan yang jarang terjadi, fase startup dan shutdown, dan jalur kode yang tidak digunakan lagi. Beban kerja ini menentukan profil yang menjadi masukan bagi pengoptimal.

  3. Jalankan xperf menggunakan jalur yang terdeteksi. Gunakan jalur yang Anda identifikasi di Pilih metode pembuatan profil Anda (LBR, PMC, atau timer OS). Mulai xperf, jalankan beban kerja sekali, hentikan xperf, dan ambil file ETL.

  4. Untuk jalur timer PMC atau OS, jalankan SPTAggregate dan SPDConvert dengan bendera yang benar /mode . Konversi ETL ke SPT lalu ke SPD. Gunakan /mode:LBR untuk data LBR; gunakan /mode:IP untuk data timer PMC atau OS.

  5. Bangun ulang dengan /spdin:<your-spd-path>. Kompilasi aplikasi Anda dengan SPD yang diisi:

    cl /Zi /EHsc /GL /O2 yourApp.cpp /link /debug /spgo /spdin:yourApp.spd
    
  6. Ukur sebelum dan sesudah. Jalankan beban kerja Anda dengan biner yang tidak dioptimalkan dan biner yang dioptimalkan dengan SPGO. Kumpulkan median dari beberapa kali pengujian untuk setiap konfigurasi. Satu kali pengujian tidak cukup andal sebagai tolok ukur.

  7. Simpan file .spd di sistem kontrol sumber. Masukkan file .spd ke dalam sistem kontrol versi Anda bersama kode sumber Anda.

  8. Aktifkan SPGO dalam build Rilis untuk pengembang. Jadikan build Rilis tim Anda menggunakan biner yang dioptimalkan dengan SPGO yang sama seperti yang digunakan di produksi. Ini membantu menangkap regresi performa lebih awal.

  9. Nonaktifkan SPGO dalam build Debug.

  10. Tonton statistik kelengkapan profil linker. Setelah setiap build dengan /spgo, perhatikan persentase fungsi yang diprofilkan yang dioptimalkan menggunakan data profil. Jika nilainya turun secara signifikan (di bawah 90%), profilkan ulang biner yang digunakan saat ini. Perubahan kode menumpuk dan SPD dapat menjadi kedaluwarsa.

Alternatif untuk menggunakan xperf

Cara lain untuk mengumpulkan data profil adalah dengan menggunakan profiler pengambilan sampel seperti Windows Performance Recorder (WPR). WPR diinstal secara default pada Windows 10 dan yang lebih baru. Ini mengumpulkan data yang serupa dengan xperf. Anda dapat mengonfigurasi WPR untuk mengumpulkan sampel CPU dengan stack panggilan, lalu mengekspor data ke file ETL yang dapat Anda proses dengan SPTAggregate dan SPDConvert seperti ETL xperf. Berikut adalah contoh penggunaan WPR untuk mengumpulkan data profil:

wpr -start CPU.light -filemode
textCount.exe < warAndPeace.txt
wpr -stop spgo_data.etl

Untuk informasi selengkapnya tentang menggunakan WPR, lihat Gunakan Perekam Performa Windows.

Distribusi SPD

Kamu bisa:

  • Masukkan file .spd langsung ke sistem kontrol versi bersama kode sumber Anda.
  • Bagikan file .spd tersebut dengan anggota tim agar mereka dapat melakukan build dengan pengoptimalan SPGO tanpa melakukan pemrofilan ulang.
  • Kemas file .spd bersama biner Anda sebagai artefak berversi (misalnya, paket NuGet), dan catat versi yang terkait dengan setiap biner.
  • Buat ulang file .spd kapan saja dengan mengulangi alur kerja pembuatan profil.

SPD terkait dengan biner persis yang menjadi dasar pembuatannya. Setelah perubahan kode yang signifikan, lakukan pembuatan profil ulang untuk menghasilkan SPD baru. Selama proses /spdin build, kompiler juga menghasilkan file .spd baru. Simpan SPD baru ini sebagai artefak build - ini adalah titik awal untuk iterasi pembuatan profil Anda berikutnya.

Penggunaan kembali informasi SPD di seluruh build

Konsep "carry forward" di SPGO memungkinkan Anda menambahkan data pembuatan profil ke file SPD yang ada tanpa membuat profil semua skenario Anda lagi dari awal dan tanpa kehilangan informasi profil yang ada. Anda juga dapat menyesuaikan berapa banyak bobot yang akan diberikan ke data profil yang lebih lama. Fleksibilitas ini berguna ketika mungkin ada perubahan perilaku dari waktu ke waktu dan Anda tidak ingin sepenuhnya kehilangan informasi pembuatan profil dari skenario sebelumnya yang berjalan. Misalnya, DLL dapat menerima pemanggilan API yang berbeda seiring aplikasi yang memanggilnya berkembang. Anda masih menginginkan pengoptimalan berdasarkan cara kerjanya dulu, tetapi juga ingin memadukan peluang untuk pengoptimalan berdasarkan cara kerjanya yang kini terkadang berbeda. Anda dapat mengembangkan profil dari waktu ke waktu dengan mencampur data lama dan baru.

Saat Anda menjalankan SPDConvert dengan file SPT baru, berikan nama file SPD yang ada. Kemudian, gunakan opsi /retire:N untuk mengontrol seberapa agresif SPDConvert mengurangi penekanan pada data profil lama saat Anda menambahkan file SPT baru:

  • Default (/retire:8) memberikan bobot lebih besar pada data yang lebih baru.
  • Gunakan /retire:0 untuk memberikan bobot yang sama untuk semua eksekusi.
  • Gunakan /retire:16 agar hanya data terbaru yang dihitung.

Troubleshooting

Temukan masalah Anda:

Masalah jalur LBR

Problem Kemungkinan penyebabnya Perbaiki
Nol sampel LBR dalam keluaran SPTAggregate CPU tidak mendukung LBR, atau VM tidak mengekspos LBR Jalankan perintah deteksi dari Deteksi jalur Anda. Jika dalam VM Hyper-V, jalankan Set-VMProcessor MyVMName -Perfmon @("pmu", "lbr") pada host. Jika LBR tidak tersedia, beralihlah ke jalur timer PMC atau OS.
Prosesor mendukung LBR tetapi SPTAggregate menunjukkan 0 sampel LBR perfcore.ini Pendaftaran DLL tidak lengkap Selesaikan perfcore.ini penyiapan dalam Configure perfcore.ini. Pastikan perf_lbr.dll terdaftar.
SPDConvert gagal atau menghasilkan SPD kosong Flag /mode salah, atau SPT hanya berisi sampel ber-mode IP Pastikan SPTAggregate keluaran menunjukkan sampel LBR. Jika output hanya menunjukkan sampel mode IP, beralihlah ke /mode:IP.

Masalah pada jalur PMC

Problem Kemungkinan penyebabnya Perbaiki
Tidak ada sampel PMC dalam keluaran SPTAggregate perfcore.ini Pendaftaran DLL salah Selesaikan perfcore.ini penyiapan dalam Configure perfcore.ini. Pastikan perf_spt.dll terdaftar. Tanpa DLL ini, xperf menghasilkan sampel PMC nol tanpa pesan kesalahan.
Jalankan xperf.exe -pmcsources untuk melihat daftar sumber Penghitung Kinerja yang tersedia di CPU Anda. Jika Anda tidak melihat entri seperti SPT_OP_RETIRE_INSTR atau SPT_OP_RETIRE_BR_INSTRSPT_OP_ETW_INSTR, maka pendaftaran DLL di perfcore.ini mungkin tidak lengkap atau CPU Anda mungkin tidak mendukung PMC. Jika Anda tidak dapat mengatasi masalah registrasi DLL, coba metode timer OS sebagai alternatif.
findstr InstructionRetired mengembalikan output tetapi xperf tidak menghasilkan sampel Pemaskingan VM pada penghitung PMC Periksa apakah berjalan di VM. Aktifkan PMU di Hyper-V dengan Set-VMProcessor, atau beralih ke jalur timer OS.
SPDConvert gagal pada jalur PMC Menggunakan /mode:LBR pada SPT khusus IP Beralih ke /mode:IP.

Masalah jalur timer OS

Problem Kemungkinan penyebabnya Perbaiki
Peningkatan yang lebih sedikit dari yang diharapkan Sesuai perkiraan - timer OS memiliki presisi yang lebih rendah Ini normal. Pengoptimal memiliki lebih sedikit informasi aliran cabang yang berasal dari sampel timer dibandingkan dari LBR atau PMC. Peningkatan performa lebih kecil. Pertimbangkan untuk meningkatkan ke PMC atau LBR jika perangkat keras mendukungnya.
Sampel timer bernilai nol xperf tidak dijalankan dalam prompt dengan hak istimewa administrator, atau penyedia PROFILE tidak ada Pastikan dijalankan sebagai Administrator. Pastikan -stackwalk profile telah diberikan kepada perintah xperf.

Masalah umum (semua jalur)

Problem Kemungkinan penyebabnya Perbaiki
"failed to configure counters" Kesalahan xperf tidak berjalan sebagai administrator Mulai ulang prompt perintah sebagai Administrator (klik > kanan Jalankan sebagai administrator). xperf memerlukan hak istimewa yang ditingkatkan untuk mengonfigurasi penghitung kinerja perangkat keras.
xperf tidak ditemukan xperf.exe tidak ada di PATH Konfirmasikan bahwa ADK Windows terinstal. Periksa C:\Program Files (x86)\Windows Kits\10\Toolkit Performa Windows\. Tambahkan direktori tersebut ke PATH Anda, atau jalankan xperf dari direktori tersebut secara langsung.
textCount.etl tidak dibuat xperf gagal diam-diam Pastikan dijalankan sebagai administrator. Jalankan ulang perintah xperf start dan periksa keluaran kesalahan.
SPTAggregate gagal dengan "biner tidak ditemukan" textCount.exe tidak dalam direktori saat ini atau jalur yang salah Konfirmasikan bahwa Anda berada di direktori yang sama dengan textCount.exe, atau berikan jalur lengkap ke /binary parameter .
File SPD tidak dibuat SPDConvert Gagal Periksa bahwa ukuran textCount.spt tidak nol. Jalankan SPTDump.exe textCount.spt untuk memeriksa kontennya.
/spdin build tidak menghasilkan peningkatan Ketidakcocokan GUID/age antara SPD dan file biner SPD dibuat dari textCount.exe yang berbeda. Profilkan build saat ini lagi untuk menghasilkan SPD baru.
Kesalahan versi MSVC pada /spgo Toolset MSVC yang lebih lama dari v14.51 Buka Visual Studio Installer >Individual Components> menginstal MSVC v14.51 atau yang lebih baru. Buka kembali Developer Command Prompt.

Langkah berikutnya

Setelah menyelesaikan tutorial ini, jelajahi kemampuan ini untuk mendapatkan lebih banyak dari SPGO:

  • Penggabungan profil: Jalankan beberapa beban kerja, kumpulkan file SPT dari setiap proses, dan teruskan semuanya ke SPDConvert. SPD campuran mencerminkan berbagai pola penggunaan nyata dan menghasilkan pengoptimalan yang lebih baik daripada profil skenario tunggal. Gunakan opsi /retire:N untuk mengontrol seberapa besar SPDConvert mengurangi penekanan pada data profil lama saat Anda menambahkan file SPT baru. Default (/retire:8) memberikan bobot lebih besar pada data yang lebih baru. Gunakan /retire:0 untuk memberi bobot yang sama pada semua proses; gunakan /retire:16 agar hanya data terbaru yang dihitung.
  • Hasil terbaik berasal dari memadukan profil dari beberapa sumber seperti tolok ukur yang menekankan skenario kunci ditambah data dunia nyata (jika tersedia). Kirimkan file SPT dari semua sumber ke SPDConvert. Ulangi file SPT dalam daftar argumen untuk memberinya lebih banyak bobot (misalnya, SPDConvert myapp.spd critical.spt critical.spt common.spt bobot critical.spt dua kali lebih berat daripada common.spt).
  • Pengoptimalan berulang: Setiap pembangunan ulang dengan /spdin menghasilkan SPD baru. Anda dapat mengulangi siklus menjalankan, membuat profil, dan mengompilasi ulang. Iterasi berikutnya mungkin memberikan hasil yang semakin berkurang, tetapi pemeriksaan kedua terkadang dapat menangkap pola yang terlewat pada percobaan pertama.
  • Perubahan kode: Setelah perubahan signifikan pada kode sumber, kumpulkan kembali data profil. SPD yang ada terikat pada biner yang digunakan saat pemrofilannya dilakukan. Ini tidak akan cocok dengan biner yang dibangun kembali secara substansial.
  • Kemutakhiran profil: Linker melaporkan persentase fungsi yang diprofilkan dan dioptimalkan menggunakan data profil setelah setiap /spdin pembuatan. Jika persentase ini turun secara signifikan, itu adalah sinyal bahwa kode telah berbeda dari profil. Buat ulang profil biner saat ini.