Öğretici: Derleme zamanında işlev inlining sorunlarını giderme

C++ projelerinizde işlev iç hatlarının derleme zamanı üzerindeki etkisini gidermek için Derleme İçgörüleri İşlevleri görünümünü kullanın.

Önkoşullar

  • Visual Studio 2022 17.8 veya üzeri.
  • C++ ile Masaüstü geliştirme iş yükünü veya C++ ile oyun geliştirme iş yükünü yüklerseniz, C++ Derleme içgörüleri varsayılan olarak etkinleştirilir.

C++ iş yükünün seçili olduğu Masaüstü geliştirme Visual Studio Yükleyicisi ekran görüntüsü.

Yüklü bileşenlerin listesi gösterilir. C++ Derleme İçgörüleri vurgulanır ve seçilir; bu da yüklü olduğu anlamına gelir.

C++ iş yükünün seçili olduğu Oyun geliştirme Visual Studio Yükleyicisi ekran görüntüsü.

Yüklü bileşenlerin listesi gösterilir. C++ Derleme İçgörüleri vurgulanır ve seçilir; bu da yüklü olduğu anlamına gelir.

Genel bakış

Visual Studio ile tümleştirilmiş olan Build Insights, özellikle AAA oyunları gibi büyük projeler için derleme sürelerinizi iyileştirmenize yardımcı olur. Derleme İçgörüleri, derleme sırasında pahalı kod oluşturmayı tanılamaya yardımcı olan İşlevler görünümü gibi analizler sağlar. Her işlev için kod oluşturma süresini ve etkisini __forceinlinegösterir.

yönergesi __forceinline , derleyiciye boyutuna veya karmaşıklığından bağımsız olarak bir işlevi satır içi olarak göndermesini söyler. İşlevin çizilmesi, işlevi çağırma ek yükünü azaltarak çalışma zamanı performansını geliştirebilir. Bunun dezavantajı, ikilinin boyutunu artırabilmesi ve derleme sürelerinizi etkileyebilecek olmasıdır.

İyileştirilmiş derlemeler için, kod oluşturmak için harcanan süre toplam derleme süresine önemli ölçüde katkıda bulunur. Genel olarak, C++ işlev iyileştirmesi hızlı bir şekilde gerçekleşir. İstisnai durumlarda, bazı işlevler iyileştirici üzerinde baskı oluşturacak ve derlemelerinizi önemli ölçüde yavaşlatacak kadar büyük ve karmaşık hale gelebilir.

Bu makalede, derlemenizdeki inlining performans sorunlarını bulmak için Derleme İçgörüleri İşlevleri görünümünü kullanmayı öğrenin.

Derleme seçeneklerini ayarlama

hata ayıklama derlemeleri __forceinline__forceinline bu iyileştirmeyi devre dışı bırakan derleyici anahtarını kullandığından, sonuçlarını ölçmek için yayın derlemesi kullanın /Ob0. Release ve x64 için derlemeyi ayarlayın:

  1. Çözüm Yapılandırmaları açılan listesinde Yayın'ı seçin.
  2. Çözüm Platformları açılan listesinde x64'i seçin.

Sürüm olarak ayarlanan Çözüm Yapılandırması açılan listesinin ve x64 olarak ayarlanan Çözüm Platformu açılan listesinin ekran görüntüsü.

İyileştirme düzeyini en yüksek iyileştirmeye ayarlayın:

  1. Çözüm Gezgini proje adına sağ tıklayın ve Özellikler'i seçin.

  2. Proje özelliklerinde C/C++>İyileştirme'ye gidin.

  3. İyileştirme açılan listesini Maksimum İyileştirme (İyileştirme Hızı) (/O2)olarak ayarlayın.

    Proje özellik sayfaları iletişim kutusunun ekran görüntüsü. Ayarlar, Yapılandırma Özellikleri > C/C++ > İyileştirmesi'ne açıktır. İyileştirme açılan listesi Maksimum İyileştirme (İyileştirme Hızı) (/O2) olarak ayarlanır.

  4. İletişim kutusunu kapatmak için Tamam'a tıklayın.

Build Insights'ı çalıştırma

Seçtiğiniz bir projede ve önceki bölümde ayarlanan Sürüm derleme seçeneklerini kullanarak Derleme İçgörüleri'ni çalıştırmak için Seçim>Yeniden Derlemesi'nde Derleme>İçgörülerini Çalıştır ana menüsünden seçim yapın. Ayrıca çözüm gezgininde bir projeye sağ tıklayıp Derleme İçgörülerini>Yeniden Derlemeyi Çalıştır'ı seçebilirsiniz. Şu anda yalnızca birkaç dosya için değil, tüm projenin derleme süresini ölçmek için Derleme yerine Yeniden Oluştur'u seçin.

Seçim > Yeniden Derlemesinde Derleme İçgörülerini Çalıştır'ın seçili olduğu ana menünün ekran görüntüsü.

Derleme tamamlandığında bir Olay İzleme Günlüğü (ETL) dosyası açılır. Windows TEMP ortam değişkeninin işaret ettiği klasöre kaydedilir. Oluşturulan ad, koleksiyon süresini temel alır.

İşlev görünümü

ETL dosyasının penceresinde İşlevler sekmesini seçin. Derlenen işlevleri ve her işlev için kodu oluşturmak için geçen süreyi gösterir. bir işlev için oluşturulan kod miktarı göz ardı edilebilirse, derleme olayı toplama performansının düşürülmesi için listede görünmez.

Build Insights İşlevleri görünüm dosyasının ekran görüntüsü.

İşlev Adı sütununda performPhysicsCalculations() vurgulanır ve bir yangın simgesiyle işaretlenir.:::

Saat [sn, %] sütunu, her işlevin duvar saati sorumluluk süresinde (WCTR) derlenmiş olması için ne kadar sürdüğünü gösterir. Bu ölçüm, paralel derleyici iş parçacıklarının kullanımına göre duvar saati saatini işlevler arasında dağıtır. Örneğin, iki farklı iş parçacığı bir saniyelik bir süre içinde iki farklı işlevi aynı anda derlediyse, her işlevin WCTR'si 0,5 saniye olarak kaydedilir. Bu, her işlevin toplam derleme süresindeki oransal payını yansıtır ve her biri paralel yürütme sırasında kullanılan kaynakları dikkate alır. Bu nedenle WCTR, birden çok derleme etkinliğinin aynı anda gerçekleştiği ortamlarda her işlevin genel derleme süresi üzerindeki etkisinin daha iyi bir ölçüsünü sağlar.

Forceinline Size sütunu, işlev için kabaca kaç yönerge oluşturulduğunu gösterir. İşlev adından önceki köşeli çift ayraça tıklayarak bu işlevde genişletilen tek tek satır içi işlevlerin her biri için kabaca kaç yönerge oluşturulduğunu görebilirsiniz.

Hangi işlevlerin derlenmesi en çok zaman aldığını görmek için Saat sütununa tıklayarak listeyi sıralayabilirsiniz. 'Fire' simgesi, bu işlevi oluşturma maliyetinin yüksek olduğunu ve araştırmaya değer olduğunu gösterir. İşlevlerin aşırı kullanımı, derlemeyi __forceinline önemli ölçüde yavaşlatabilir.

Filtre İşlevleri kutusunu kullanarak belirli bir işlevi arayabilirsiniz. İşlevin kod oluşturma süresi çok küçükse İşlevler Görünümü'nde görünmez.

İşlev inlining'ini ayarlayarak derleme süresini iyileştirme

Bu örnekte işlevin performPhysicsCalculations derlenmiş olması en çok zaman alır.

Build Insights İşlevleri görünümünün ekran görüntüsü.

İşlev Adı sütununda performPhysicsCalculations() vurgulanır ve bir yangın simgesiyle işaretlenir.

Bu işlevden önce köşeli çift ayraç seçip Forceinline Size sütununu en yüksekten en düşüğe doğru sıralayarak daha fazla araştırma yaparak soruna en büyük katkıda bulunanları görüyoruz.

Genişletilmiş işlev içeren Build Insights İşlevleri görünümünün ekran görüntüsü.

performPhysicsCalculations() genişletilir ve içinde çizili olan işlevlerin uzun bir listesini gösterir. complexOperation( ), recursiveHelper() ve sin() gibi işlevlerin birden çok örneği gösterilmiştir. Forceinline Size sütunu, complexOperation() işlevinin 315 yönergedeki en büyük satır içi işlev olduğunu gösterir. recursiveHelper() 119 yönergeye sahiptir. Sin() 75 yönergeye sahiptir, ancak diğer işlevlerden çok daha fazla örneği vardır.

Ve gibi Vector2D<float>::complexOperation() Vector2D<float>::recursiveHelper() soruna katkıda bulunan daha büyük iç işlevler vardır. Ancak , , Vector2d<float>::cos(float)Vector2D<float>::power(float,int)ve Vector2D<float>::factorial(int)örneklerinin Vector2d<float>::sin(float)birçok örneği (burada gösterilmez) vardır. Bunları eklediğinizde, oluşturulan yönergelerin toplam sayısı daha büyük olan birkaç işlevi hızla aşıyor.

Kaynak koddaki bu işlevlere baktığımızda yürütme süresinin döngülerin içinde harcanacağını görüyoruz. Örneğin, için kod factorial()aşağıda verilmişti:

static __forceinline T factorial(int n)
{
    T result = 1;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < i; ++j) {
            result *= (i - j) / (T)(j + 1);
        }
    }
    return result;
}

Bu işlevi çağırmanın genel maliyeti, işlevin maliyetiyle karşılaştırıldığında önemsiz olabilir. İşlevi çağırmak için geçen süre (yığında bağımsız değişkenleri gönderme, işleve atlama, dönüş bağımsız değişkenlerini alma ve işlevden dönme) işlevin yürütülmesi için geçen süreye ve işleve çok fazla çağrıldığında, satır içi işlev yapmak en yararlı olacaktır. Böyle bir durum söz konusu olmadığında, satır içi hale getirildiğinde azalan geri dönüşler olabilir. Derleme süresine __forceinline yardımcı olup olmadığını görmek için yönergesini kaldırmayı deneyebiliriz. ve cos() için kodpowersin(), kodun birçok kez yürütülecek bir döngüden oluşmasına benzer. Yönergeyi bu işlevlerden kaldırmayı __forceinline da deneyebiliriz.

Derleme İçgörüleri'ni Seçim>Yeniden Oluşturmada Derleme>İçgörülerini Çalıştır'ı seçerek ana menüden yeniden çalıştırıyoruz. Ayrıca çözüm gezgininde bir projeye sağ tıklayıp Derleme İçgörülerini>Yeniden Derlemeyi Çalıştır'ı seçebilirsiniz. Daha önce olduğu gibi tüm projenin derleme süresini ölçmek için Derleme yerine Yeniden Derle'yi seçiyoruz ve şu anda yalnızca birkaç dosya kirli olmayabilir.

Derleme süresi 25,181 saniyeden 13,376 saniyeye çıkar ve performPhysicsCalculations işlev sayılacak derleme süresine yeterince katkıda bulunmadığından İşlevler görünümünde artık gösterilmez.

2B vektör üst bilgi dosyasının ekran görüntüsü.

İşlev Adı sütununda performPhysicsCalculations() vurgulanır ve bir yangın simgesiyle işaretlenir.:::

Tanılama Oturumu süresi, derlemeyi gerçekleştirmenin yanı sıra Build Insights verilerini toplamaya yönelik ek yüklerin toplam süresidir.

Bir sonraki adım, uygulamanın performansının değişiklik tarafından olumsuz etkilenip etkilenmediğini görmek için uygulamanın profilini almak olacaktır. Bu durumda, gerektiğinde seçmeli olarak geri ekleyebiliriz __forceinline .

bu dosyanın kaynak kodunu açmak için İşlevler görünümündeki bir dosyaya çift tıklayın, sağ tıklayın veya Enter tuşuna basın.

İşlevler görünümünde bir dosyaya sağ tıklama işleminin ekran görüntüsü. Kaynak Dosyaya Git menü seçeneği vurgulanır.

İpuçları

  • Derleme zamanının kaydını tutmak için ETL Dosyası Olarak Kaydet'i daha kalıcı bir konuma kaydedebilirsiniz.> Daha sonra değişikliklerinizin derleme süresini geliştirip geliştirmediğini görmek için bunu gelecekteki derlemelerle karşılaştırabilirsiniz.
  • Build Insights penceresini yanlışlıkla kapatırsanız, dosyayı geçici klasörünüzde bularak <dateandtime>.etl yeniden açın. TEMP Windows ortam değişkeni, geçici dosyalar klasörünüzün yolunu sağlar.
  • Windows Performans Analizi (WPA) ile Build Insights verilerini incelemek için ETL penceresinin sağ alt kısmındaki WPA'da Aç düğmesine tıklayın.
  • Sütunları sürükleyerek sütunların sırasını değiştirin. Örneğin, Time sütununu ilk sütun olarak taşımayı tercih edebilirsiniz. Sütun üst bilgisine sağ tıklayıp görmek istemediğiniz sütunların seçimini kaldırarak sütunları gizleyebilirsiniz.
  • İşlevler görünümü, ilgilendiğiniz bir işlevi bulmak için bir filtre kutusu sağlar. Sağladığınız adla kısmi eşleşmeler yapar.
  • İşlevler görünümünün size göstermeye çalıştığı şeyi yorumlamayı unutursanız, görünümü açıklayan bir araç ipucu görmek için sekmenin üzerine gelin. İşlevler sekmesinin üzerine gelirseniz, araç ipucu şunları söyler: "Alt düğümlerin zorla gelen işlevler olduğu işlevlerin istatistiklerini gösteren görünüm."

Sorun giderme

  • Derleme İçgörüleri penceresi görünmüyorsa derleme yerine yeniden derleme yapın. Hiçbir şey gerçekten derlenmiyorsa Build Insights penceresi görünmez; son derlemeden bu yana hiçbir dosya değişmediyse bu durum söz konusu olabilir.
  • İşlevler görünümünde herhangi bir işlev gösterilmiyorsa, doğru iyileştirme ayarlarıyla oluşturmuyor olabilirsiniz. Derleme seçeneklerini ayarlama bölümünde açıklandığı gibi Tam iyileştirmelerle Yayın'ı derlediğinizden emin olun. Ayrıca, bir işlevin kod oluşturma süresi çok küçükse, listede görünmez.

Ayrıca bkz.

Satır içi işlevler (C++)
Daha hızlı C++ derlemeleri, basitleştirilmiş: zaman için yeni ölçüm
Visual Studio'da İçgörüler Oluşturma videosu - Pure Virtual C++ 2023
Derleme süresi üzerindeki üst bilgi dosyası etkisi sorunlarını giderme
Visual Studio 2022 17.8'de Build Insights için İşlevler Görünümü
Öğretici: vcperf ve Windows Performans Analizi
C++ Build Insights ile kod oluşturma süresini geliştirme