Aracılığıyla paylaş


En iyi uygulamaları iyileştirme

Bu belgede, Visual Studio'da C++ programlarını iyileştirmeye yönelik bazı en iyi yöntemler açıklanmaktadır.

Derleyici ve Bağlayıcı Seçenekleri

Profil destekli iyileştirme

Visual Studio, profil destekli iyileştirmeyi (PGO) destekler. Bu iyileştirme, uygulamanın daha sonra en iyi duruma getirilmesini sağlamak için bir uygulamanın izlemeli sürümünün eğitim yürütmelerinden profil verilerini kullanır. PGO kullanmak zaman alabilir, bu nedenle her geliştiricinin kullandığı bir şey olmayabilir, ancak ürünün son sürümü için PGO kullanmanızı öneririz. Daha fazla bilgi için bkz . Profil Destekli İyileştirmeler.

Ayrıca, Tüm Program İyileştirmesi (Bağlantı Zaman Kodu Oluşturma olarak da bilinir) ve /O1 ve /O2 iyileştirmeleri geliştirilmiştir. Genel olarak, bu seçeneklerden biriyle derlenen bir uygulama, önceki derleyiciyle derlenen uygulamadan daha hızlı olacaktır.

Daha fazla bilgi için bkz /GL . (Tüm Program İyileştirme) ve /O1/O2 (Boyutu Küçült, Hızı En Üst Düzeye Çıkar).

Kullanılacak iyileştirme düzeyi

Mümkünse, son sürüm derlemeleri Profil Destekli İyileştirmeler ile derlenmelidir. İzlemeli derlemeleri çalıştırmak için altyapı yetersiz olduğundan veya senaryolara erişemediğinden dolayı PGO ile derleme yapmak mümkün değilse, Tüm Program İyileştirmesi ile derlemenizi öneririz.

Anahtar /Gy da çok kullanışlıdır. Her işlev için ayrı bir COMDAT oluşturur ve başvurulmayan COMDAT'ları ve COMDAT katlamasını kaldırma konusunda bağlayıcıya daha fazla esneklik sağlar. Kullanmanın /Gy tek dezavantajı, hata ayıklama sırasında sorunlara neden olabilmesidir. Bu nedenle, genellikle kullanılması önerilir. Daha fazla bilgi için bkz /Gy . (İşlev Düzeyi Bağlamayı Etkinleştirme).

64 bit ortamlarda bağlantı için bağlayıcı seçeneğinin /OPT:REF,ICF kullanılması önerilir ve 32 bit ortamlarda /OPT:REF kullanılması önerilir. Daha fazla bilgi için bkz . /OPT (İyileştirmeler).

Ayrıca, iyileştirilmiş sürüm derlemelerinde bile hata ayıklama sembolleri oluşturmanız kesinlikle önerilir. Oluşturulan kodu etkilemez ve gerekirse uygulamanızda hata ayıklamayı çok daha kolay hale getirir.

Kayan nokta anahtarları

Derleyici /Op seçeneği kaldırıldı ve kayan nokta iyileştirmeleriyle ilgili aşağıdaki dört derleyici seçeneği eklendi:

Seçenek Açıklama
/fp:precise Bu varsayılan öneridir ve çoğu durumda kullanılmalıdır.
/fp:fast Performans, örneğin oyunlarda son derece önemliyse önerilir. Bu, en hızlı performansa neden olur.
/fp:strict Hassas kayan nokta özel durumları ve IEEE davranışı isteniyorsa önerilir. Bu en yavaş performansa neden olur.
/fp:except[-] veya /fp:preciseile /fp:strict birlikte kullanılabilir, ancak kullanılamaz/fp:fast.

Daha fazla bilgi için bkz /fp . (Kayan Nokta Davranışını Belirtme).

İyileştirme declspecs

Bu bölümde, performansa yardımcı olmak için programlarda kullanılabilecek iki declspec'e bakacağız: __declspec(restrict) ve __declspec(noalias).

restrict Declspec yalnızca işaretçi döndüren işlev bildirimlerine uygulanabilir, örneğin__declspec(restrict) void *malloc(size_t size);

declspec restrict , sarmalanmamış işaretçiler döndüren işlevlerde kullanılır. Bu anahtar sözcük, geçerli programda zaten kullanımda olan bir işaretçi değerini hiçbir zaman döndürmeyeceğinden C-Runtime Kitaplığı uygulaması malloc için kullanılır (boşaltıldıktan sonra bellek kullanma gibi geçersiz bir şey yapmazsanız).

restrict declspec, derleyiciye derleyici iyileştirmeleri gerçekleştirmek için daha fazla bilgi verir. Derleyicinin belirlemesi en zor şeylerden biri, hangi işaretçilerin diğer işaretçileri diğer adlarıyla kullandığıdır ve bu bilgilerin kullanılması derleyiciye büyük ölçüde yardımcı olur.

Bunun derleyicinin doğrulanacağı bir şey değil, derleyiciye verilen bir söz olduğunu belirtmek gerekir. Programınız bu restrict declspec'i uygunsuz bir şekilde kullanıyorsa, programınızın davranışı yanlış olabilir.

Daha fazla bilgi için bkz. restrict.

noalias Declspec yalnızca işlevlere de uygulanır ve işlevin yarı saf bir işlev olduğunu gösterir. Yarı saf işlev yalnızca yerellere, bağımsız değişkenlere ve bağımsız değişkenlerin birinci düzey dolaylılarına başvuran veya değiştiren işlevdir. Bu declspec derleyiciye verilen bir vaattir ve işlev genel değerlere veya işaretçi bağımsız değişkenlerinin ikinci düzey dizinlerine başvuruda bulunursa derleyici uygulamayı bozan kod oluşturabilir.

Daha fazla bilgi için bkz. noalias.

İyileştirme pragmaları

Ayrıca kodu iyileştirmeye yardımcı olmak için birkaç yararlı pragma vardır. İlk olarak şu konuyu ele #pragma optimizealacağız:

#pragma optimize("{opt-list}", on | off)

Bu pragma, belirli bir iyileştirme düzeyini işlev temelinde ayarlamanıza olanak tanır. Bu, belirli bir işlev iyileştirmeyle derlendiğinde uygulamanızın kilitlendiği nadir durumlar için idealdir. Tek bir işlev için iyileştirmeleri kapatmak için bunu kullanabilirsiniz:

#pragma optimize("", off)
int myFunc() {...}
#pragma optimize("", on)

Daha fazla bilgi için bkz. optimize.

Satır içi, derleyicinin gerçekleştirdiği en önemli iyileştirmelerden biridir ve burada bu davranışı değiştirmeye yardımcı olan birkaç pragmadan bahsediyoruz.

#pragma inline_recursion , uygulamanın özyinelemeli bir çağrıyı satır içi olarak sıralayabilmesini isteyip istemediğinizi belirtmek için yararlıdır. Varsayılan olarak kapalıdır. Küçük işlevlerin basit özyinelemeleri için bunu açabilirsiniz. Daha fazla bilgi için bkz. inline_recursion.

Inlining derinliğini sınırlamak için bir diğer yararlı pragma da şeklindedir #pragma inline_depth. Bu genellikle bir programın veya işlevin boyutunu sınırlamaya çalıştığınız durumlarda kullanışlıdır. Daha fazla bilgi için bkz. inline_depth.

__restrict ve __assume

Visual Studio'da performansa yardımcı olabilecek birkaç anahtar sözcük vardır: __restrict ve __assume.

İlk olarak, ve iki farklı şey olduğu __restrict __declspec(restrict) belirtilmelidir. Bir şekilde ilişkili olsalar da semantikleri farklıdır. __restrict veya gibi const volatilebir tür niteleyicidir, ancak yalnızca işaretçi türleri için kullanılır.

ile __restrict değiştirilen bir işaretçi, __restrict işaretçisi olarak adlandırılır. __restrict işaretçisi, yalnızca __restrict işaretçisi aracılığıyla erişilebilen bir işaretçidir. Başka bir deyişle, __restrict işaretçisi tarafından işaret edilen verilere erişmek için başka bir işaretçi kullanılamaz.

__restrict Microsoft C++ iyileştiricisi için güçlü bir araç olabilir, ancak bunu büyük bir dikkatle kullanın. Düzgün kullanılmadıysa, iyileştirici uygulamanızı bozacak bir iyileştirme gerçekleştirebilir.

ile __assumebir geliştirici derleyiciye bazı değişkenlerin değeri hakkında varsayımlarda bulunmasını söyleyebilir.

Örneğin __assume(a < 5); , iyileştiriciye bu kod satırında değişkenin a 5'ten küçük olduğunu söyler. Bu da derleyiciye verilen bir sözdür. a Programda bu noktada aslında 6 ise, derleyici iyileştirildikten sonra programın davranışı beklediğiniz gibi olmayabilir. __assume en çok switch deyimleri ve/veya koşullu ifadeler öncesinde yararlıdır.

ile ilgili bazı sınırlamalar __assumevardır. İlk olarak, gibi __restrictyalnızca bir öneridir, bu nedenle derleyici bunu yoksaymak için serbesttir. Ayrıca, __assume şu anda yalnızca sabitlere karşı değişken eşitsizlikleriyle çalışır. Sembolik eşitsizlikleri yaymıyor, örneğin, varsay(b < ).

İç destek

İç bilgiler, derleyicinin çağrı hakkında iç bilgiye sahip olduğu işlev çağrılarıdır ve bir kitaplıktaki bir işlevi çağırmak yerine bu işlev için kod yayar. intrin.h> üst bilgi dosyası<, desteklenen donanım platformlarının her biri için tüm kullanılabilir iç bilgileri içerir.

İç bilgi, programcıya derlemeyi kullanmak zorunda kalmadan kodun derinliklerine inebilme olanağı verir. İç bilgileri kullanmanın çeşitli avantajları vardır:

  • Kodunuz daha taşınabilir. Birçok iç bilgi birden çok CPU mimarisinde kullanılabilir.

  • Kodunuz daha kolay okunur çünkü kod hala C/C++ dilinde yazılmıştır.

  • Kodunuz derleyici iyileştirmelerinden yararlanır. Derleyici daha iyi hale geldiğinde, iç kod oluşturma iyileşir.

Daha fazla bilgi için bkz . Derleyici İç Bilgileri.

Özel durumlar

Özel durumlar kullanılarak ilişkilendirilmiş bir performans isabeti vardır. Derleyicinin belirli iyileştirmeleri gerçekleştirmesini engelleyen deneme blokları kullanılırken bazı kısıtlamalar uygulanır. x86 platformlarında, kod yürütme sırasında oluşturulması gereken ek durum bilgileri nedeniyle deneme bloklarından ek performans düşüşü vardır. 64 bit platformlarda deneme blokları performansı o kadar düşürmez, ancak özel durum oluşturulduktan sonra işleyiciyi bulma ve yığını geri sarma işlemi pahalı olabilir.

Bu nedenle, gerçekten ihtiyaç duymayan koda try/catch blokları eklemekten kaçınmanız önerilir. Özel durumlar kullanmanız gerekiyorsa, mümkünse zaman uyumlu özel durumlar kullanın. Daha fazla bilgi için bkz . Yapılandırılmış Özel Durum İşleme (C/C++).

Son olarak, yalnızca istisnai durumlar için özel durumlar oluşturur. Genel denetim akışı için özel durumlar kullanmak büyük olasılıkla performansı olumsuz etkileyebilir.

Ayrıca bkz.