Udostępnij za pośrednictwem


Optymalizacja najlepszych praktyk.

W tym dokumencie opisano niektóre najważniejsze wskazówki dotyczące optymalizacji w programie Visual C++.Omówiono następujące tematy:

  • Kompilator i program łączący, opcje

    • Optymalizacja z przewodnikiem profilu

    • Którego poziomu optymalizacji należy używać?

    • Szybująca przełączniki punkt

  • Optymalizacja Declspecs

  • Optymalizacja Pragmas

  • __restrict i __assume

  • Wsparcie wewnętrzne

  • Wyjątki

Kompilator i program łączący, opcje

ms235601.collapse_all(pl-pl,VS.110).gifOptymalizacja z przewodnikiem profilu

Visual C++ obsługuje optymalizacji z przewodnikiem profilu (PGO).Optymalizacja używa danych profilu z egzekucji ostatnich instrumentowanych wersji aplikacji do kierowania później optymalizacji aplikacji.Za pomocą PGO może być czasochłonne, dlatego nie może być coś, czego każdy programista używa, ale zaleca się użycie PGO dla kompilacji finalnej wersji produktu.Aby uzyskać więcej informacji, zobacz Optymalizacje przewodnikiem profilu.

Ponadto cały Program Optimization (również wie, jak generowanie kodu czasu łącza) oraz /O1 i /O2 poprawiła optymalizacje.Ogólnie rzecz biorąc aplikacja skompilowany z jedną z tych opcji będzie szybciej niż tej samej aplikacji skompilowany z wcześniejszych kompilatora.

Aby uzyskać więcej informacji, zobacz /GL (optymalizacja całego programu) i / O1, /O2 (zminimalizować rozmiar, zmaksymalizować szybkość).

ms235601.collapse_all(pl-pl,VS.110).gifKtórego poziomu optymalizacji należy używać?

Jeśli to możliwe należy sporządzić kompilacje wersja ostateczna z profilu z przewodnikiem optymalizacje.Jeśli to nie jest możliwe tworzenie z PGO, czy ze względu na niewystarczające infrastruktury dla oprzyrządowanego kompilacje uruchomiony lub nie mających dostępu do scenariuszy, sugerujemy budynku z całego programu optymalizacji.

/Gy Przełącznika jest również bardzo użyteczne.Generuje oddzielnych COMDAT dla każdej funkcji, podając łączący większą elastyczność, jeśli chodzi o usuwanie nieużywane COMDATs i COMDAT składanych.Jedyną wadą za pomocą /Gy jest, że może to mieć większego wpływu na czas kompilacji.Dlatego ogólnie zaleca się go używać.Aby uzyskać więcej informacji, zobacz /Gy (Włączanie funkcji na poziomie łączenie).

Do łączenia w środowiskach 64-bitowe, zaleca się używać /OPT:REF,ICF opcji linker i w środowiskach 32-bitowe, /OPT:REF jest zalecane.Aby uzyskać więcej informacji, zobacz / OPT (optymalizacje).

Także stanowczo zaleca się wygenerować symboli debugowania, nawet przy użyciu zoptymalizowanej wersji.Nie jej skutkiem wygenerowany kod i stwarza ona dużo łatwiej jest debugowanie aplikacji, jeśli potrzeba.

ms235601.collapse_all(pl-pl,VS.110).gifSzybująca przełączniki punkt

/Op Usunięto opcję kompilatora i dodano następujące cztery opcje kompilatora zajmujących się przestawne optymalizacje punkt:

/fp:precise

To zalecenie domyślną i powinny być stosowane w większości przypadków.

/fp:fast

Zalecane, gdy wydajność jest sprawą najwyższej wagi, na przykład w grach.Spowoduje to największą wydajność.

/fp:strict

Jeśli zalecane dokładne wyjątki zmiennoprzecinkowych i IEEE zachowanie jest pożądane.Spowoduje to jest najwolniejsza.

/fp:except[-]

Mogą być używane w połączeniu z /fp:strict lub /fp:precise, ale nie /fp:fast.

Aby uzyskać więcej informacji, zobacz / ol (określić zachowanie zmiennoprzecinkowych).

Optymalizacja Declspecs

W tej sekcji zostanie patrzymy na dwóch declspecs, używane w programach w celu wydajności: __declspec(restrict) i __declspec(noalias).

restrict Declspec mogą być stosowane tylko do deklaracji funkcji zwracających wskaźnik, takie jak__declspec(restrict) void *malloc(size_t size);

restrict Declspec jest używana w funkcji, które zwracają wskaźniki unaliased.Słowo kluczowe this jest używany do wykonania C Runtime Library malloc , ponieważ nigdy nie będzie ona zwracać wartość wskaźnika, który jest już używany w bieżącym programie (chyba że robisz coś nielegalne, takich jak użycie pamięci po jej zwolnieniu).

restrict Declspec daje kompilator więcej informacji do wykonywania optymalizacje kompilatora.Jeden najtrudniejsze rzeczy dla kompilatora ustalić jest alias wskaźniki, jakie inne wskaźniki i korzystanie z tej informacji znacznie ułatwia kompilator.

Warto wskazujące, że jest to promise do kompilatora, nie coś, co będzie sprawdzać, kompilator.Jeśli Twój program używa tego restrict declspec niewłaściwie, program może mieć nieprawidłowe zachowanie.

Aby uzyskać więcej informacji, zobacz restrict.

noalias Declspec jest również zastosowane tylko do funkcji i wskazuje, że funkcja ta jest funkcją semi-pure.Funkcja semi-pure jest taki, który odwołuje się do lub modyfikuje zmiennych lokalnych, argumenty i pierwszego poziomu indirections argumentów.Jeśli funkcja odwołuje się do globalnych lub drugiego poziomu indirections argumentów wskaźnika, a następnie kompilator może wygenerować kod, podziały wierszy aplikacji i declspec ten jest promise w kompilatorze.

Aby uzyskać więcej informacji, zobacz noalias.

Optymalizacja Pragmas

Istnieją również kilka pragmas użyteczne dla pomaga zoptymalizować kod.Pierwszy z nich omówimy #pragma optimize:

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

Ta dyrektywa pragma umożliwia ustawienie poziomu optymalizacji danym na podstawie funkcji przez funkcję.Jest to doskonałe narzędzie dla tych rzadkich przypadkach gdy aplikacja ulega awarii podczas danej funkcji została skompilowana z optymalizacji.Aby wyłączyć optymalizacje pojedynczej funkcji, można użyć to:

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

Aby uzyskać więcej informacji, zobacz optimize.

Inlining jest jednym z najważniejszych optymalizacji, które wykonuje kompilator i tu mówimy o kilka pragmas, które pomagają zmodyfikować to zachowanie.

#pragma inline_recursionprzydaje się do określania, czy nie chcesz, aby aplikacja Aby móc inline wywołania rekurencyjnego.Domyślnie jest wyłączona.Shallow rekursji małych funkcji możesz ją włączyć.Aby uzyskać więcej informacji, zobacz inline_recursion.

Innym użyteczne pragma ograniczania głębokość inline jest #pragma inline_depth.Jest to zazwyczaj przydatne w sytuacjach, gdy próbujesz ograniczyć rozmiar programu lub funkcji.Aby uzyskać więcej informacji, zobacz inline_depth.

__restrict i __assume

Istnieje kilka słów kluczowych w programie Visual C++, które mogą pomóc wydajności: __restrict i __assume.

Po pierwsze, należy zauważyć, że __restrict i __declspec(restrict) to dwie różne rzeczy.Podczas gdy nieco są one związane, ich semantykę są różne.__restrictjak jest kwalifikator typu const lub volatile, ale wyłącznie dla typów wskaźników.

Wskaźnik, który zostanie zmodyfikowany z __restrict nazywa się __restrict wskaźnik.Wskaźnik __restrict znajduje się wskaźnik, który jest możliwy tylko za pomocą wskaźnika __restrict.Innymi słowy inny wskaźnik, nie można użyć do dostępu do danych wskazywanej przez kursor __restrict.

__restrictmoże być zaawansowane narzędzie Optymalizator Visual C++, ale jej używać z dużą ostrożnością.Używane w nieodpowiedni sposób Optymalizator może wykonywać Optymalizacja mogłoby doprowadzić do uszkodzenia aplikacji.

__restrict Zastępuje słowo kluczowe /Oa przełączyć się z poprzednimi wersjami.

Z __assume, deweloper może kompilatorowi poczynić założeń wartość zmiennej niektóre.

Na przykład __assume(a < 5); informuje Optymalizator, że w tym wierszu kod zmiennej a jest mniejsza niż 5.Jest to ponownie promise do kompilatora.Jeśli a jest faktycznie 6 w tym momencie w programie, a następnie zachowanie programu po optymalizacji kompilator nie może być mogą spodziewać.__assumejest najbardziej użyteczna przed do przełącznika instrukcji i/lub wyrażenia warunkowe.

Istnieją pewne ograniczenia w __assume.Po pierwsze, jak __restrict, to tylko sugestia, więc kompilator wolne ma ją ignorować.Ponadto __assume obecnie działa tylko w przypadku zmiennej nierówności przeciwko stałych.Nie propaguje symboliczne nierówności, na przykład assume(a <. b).

Wsparcie wewnętrzne

Intrinsics są funkcja wywołuje gdy kompilator wewnętrzne wiedzy o wywołaniu, i zamiast wywoływania funkcji w bibliotece, emituje kod dla tej funkcji.Intrin.h pliku nagłówka znajdującym się w \VC\include\intrin.h <Installation_Directory> zawiera wszystkie dostępne intrinsics dla każdego z trzech obsługiwanych platform (x 86, x 64 i Itanium).

Intrinsics udostępnić programiście możliwość przejdź do kodu bez konieczności korzystania z zestawu.Istnieje kilka korzyści wynikające z używania intrinsics:

  1. Kod jest bardziej poręczny.Kilka intrinsics są dostępne w wielu architektury Procesora.

  2. Kod jest bardziej czytelny, ponieważ kod nadal jest napisany w c i C++.

  3. Kod pobiera korzyści optymalizacje kompilatora.Jak kompilator pobiera lepiej, poprawia generowanie kodu dla intrinsics.

Aby uzyskać więcej informacji, zobacz Intrinsics kompilatora i Korzyści wynikające ze stosowania Intrinsics.

Wyjątki

Istnieje wydajności hit związanych z używaniem wyjątki.Niektóre ograniczenia są wprowadzane podczas korzystania z bloków try powstrzymanie kompilator z wykonywania niektórych optymalizacje.W architekturze x 86 platform, którego obniżenie wydajności dodatkowe z spróbuj bloki ze względu na Państwo dodatkowe informacje, który musi zostać wygenerowany podczas wykonywania kodu.Na platformach 64-bitowych, spróbuj bloków nie obniżyć wydajność, jaka, ale po wyjątek, proces wyszukiwania programu obsługi i niekontrolowanej stosu może być kosztowne.

Dlatego zalecane jest uniknięcie wprowadzenia bloków try i catch do kodu, który nie jest tak naprawdę potrzebna.Jeśli musisz użyć wyjątki, użyj synchroniczne wyjątków Jeśli to możliwe.Aby uzyskać więcej informacji, zobacz Strukturalnej obsługi (C++) wyjątków.

Wreszcie generują wyjątki w wyjątkowych przypadkach.Za pomocą wyjątków dla ogólnej kontroli przepływu prawdopodobnie należy ponieść wydajności.

Zobacz też

Koncepcje

Optymalizacja kodu