Jakie są zalety / wady korzystania z funkcji wbudowanych w C ++? Widzę, że zwiększa to tylko wydajność kodu generowanego przez kompilator, ale przy dzisiejszych zoptymalizowanych kompilatorach, szybkich procesorach, ogromnej pamięci itp. (Nie tak jak w 1980 r. <Gdzie pamięci było mało i wszystko musiało zmieścić się w 100 KB pamięci) co zalety, które naprawdę mają dzisiaj?
c++
inline-functions
Lennie De Villiers
źródło
źródło
inline
jest to słowo kluczowe c ++, a inlining to technika optymalizacji kompilatora. Zobacz to pytanie „ kiedy powinienem napisać słowo kluczoweinline
dla funkcji / metody ”, aby uzyskać poprawną odpowiedź.Odpowiedzi:
Funkcje śródliniowe są szybsze, ponieważ nie trzeba popychać i wyrzucać elementów na stosie, takich jak parametry i adres zwrotny; powoduje to jednak, że twój plik binarny jest nieco większy.
Czy to robi znaczącą różnicę? Większość z nich jest niewystarczająco na nowoczesnym sprzęcie. Ale może mieć znaczenie, co wystarcza niektórym ludziom.
Oznaczenie czegoś w linii nie daje gwarancji, że będzie ono w linii. To tylko propozycja dla kompilatora. Czasami nie jest to możliwe, na przykład gdy masz funkcję wirtualną lub gdy występuje rekurencja. A czasami kompilator po prostu decyduje się go nie używać.
Widziałem taką sytuację, która ma zauważalną różnicę:
źródło
Zalety
Niedogodności
Inlining Magic
return 42 ;
instrukcji. To dla mnie ekstremalne pochylenie . Zdarza się rzadko w prawdziwym życiu, wydłuża czas kompilacji, nie powoduje wzdęcia i przyspiesza kod. Ale podobnie jak graal, nie próbuj go stosować wszędzie, ponieważ większość procesów nie może być rozwiązana w ten sposób ... Mimo to jest to fajne ...:-p
źródło
3.2/6: There can be more than one definition of [..] inline function with external linkage [..] non-static function template
. W 5.1.5 / 6For a generic lambda, the closure type has a public inline function call operator member template
. I7.1.2/2: the use of inline keyword is to declare an inline function
tam, gdzie sugeruje się wstawienie ciała funkcji w punkcie wywołania. Więc do wniosku, że nawet jeśli mogą one zachowywać się tak samo, funkcje inline i szablony funkcji są nadal oddzielne, prostopadłe pojęcia, że może być mieszany (tj szablon funkcji inline)W archaicznym C i C ++
inline
jest toregister
: sugestia (nic więcej niż sugestia) dla kompilatora na temat możliwej optymalizacji.We współczesnym C ++
inline
mówi linkerowi, że jeśli wiele definicji (nie deklaracji) znajduje się w różnych jednostkach tłumaczeniowych, wszystkie są takie same, a linker może dowolnie je przechowywać i odrzucać wszystkie pozostałe.inline
jest obowiązkowe, jeśli funkcja (bez względu na to, jak złożona lub „liniowa”) jest zdefiniowana w pliku nagłówkowym, aby umożliwić włączenie wielu źródeł bez uzyskania przez linker błędu „wielu definicji”.Funkcje składowe zdefiniowane wewnątrz klasy są domyślnie „wbudowane”, podobnie jak funkcje szablonów (w przeciwieństwie do funkcji globalnych).
Zwróć uwagę na dołączenie fileA.h do dwóch plików .cpp, co powoduje dwa wystąpienia
afunc()
. Linker odrzuci jeden z nich. Jeśli nieinline
zostanie określony, linker narzeka.źródło
Inlining to propozycja dla kompilatora, którą można zignorować. Jest idealny do małych kawałków kodu.
Jeśli twoja funkcja jest wbudowana, jest ona zasadniczo wstawiana do kodu, w którym jest do niej wywoływana funkcja, zamiast wywoływać osobną funkcję. Może to pomóc z prędkością, ponieważ nie musisz wykonywać rzeczywistego połączenia.
Pomaga również procesorom w przetwarzaniu potokowym, ponieważ nie muszą one ponownie ładować potoku nowymi instrukcjami wywołanymi wywołaniem.
Jedyną wadą jest możliwy większy rozmiar pliku binarnego, ale dopóki funkcje są małe, nie będzie to miało większego znaczenia.
Tego rodzaju decyzje pozostawiam obecnie kompilatorom (cóż, zresztą te inteligentne). Ludzie, którzy je napisali, mają znacznie bardziej szczegółową wiedzę na temat architektur bazowych.
źródło
Funkcja Inline to technika optymalizacji wykorzystywana przez kompilatory. Można po prostu wstawić słowo kluczowe inline do prototypu funkcji, aby funkcja była wstawiona. Funkcja Inline instruuje kompilator, aby wstawił pełny treść funkcji, gdziekolwiek funkcja ta została użyta w kodzie.
Zalety :-
Nie wymaga narzutu wywołania funkcji.
Oszczędza to również narzutu zmiennych push / pop na stosie, podczas wywoływania funkcji.
Oszczędza to również narzutu wywołania zwrotnego z funkcji.
Zwiększa lokalizację referencji dzięki wykorzystaniu pamięci podręcznej instrukcji.
Po wstawieniu kompilator może również zastosować optymalizację wewnątrzprocesową, jeśli jest to określone. Jest to najważniejszy, w ten sposób kompilator może teraz skupić się na eliminacji martwego kodu, może kłaść większy nacisk na przewidywanie gałęzi, eliminację zmiennych indukcyjnych itp.
Aby sprawdzić więcej na ten temat, kliknij ten link http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html
źródło
Chciałbym dodać, że funkcje wbudowane są kluczowe podczas budowania biblioteki współdzielonej. Bez wbudowanej funkcji znakowania zostanie ona wyeksportowana do biblioteki w formie binarnej. Będzie również obecny w tabeli symboli, jeśli zostanie wyeksportowany. Z drugiej strony wbudowane funkcje nie są eksportowane ani do plików binarnych biblioteki, ani do tabeli symboli.
Może to mieć krytyczne znaczenie, gdy biblioteka ma być ładowana w czasie wykonywania. Może także uderzyć w biblioteki obsługujące binarnie. W takich przypadkach nie używaj wbudowanego.
źródło
inline
podczas budowania biblioteki współdzielonej!Podczas optymalizacji wiele kompilatorów wstawia funkcje, nawet jeśli ich nie zaznaczyłeś. Zasadniczo wystarczy oznaczyć funkcje jako wbudowane, jeśli wiesz coś, czego nie ma kompilator, ponieważ zwykle może on sam podjąć właściwą decyzję.
źródło
inline
pozwala umieścić definicję funkcji w pliku nagłówkowym, a#include
ten plik nagłówkowy w wielu plikach źródłowych, bez naruszania reguły jednej definicji.źródło
Ogólnie rzecz biorąc, w dzisiejszych czasach każdy nowoczesny kompilator martwiący się o wstawianie czegokolwiek jest właściwie stratą czasu. Kompilator powinien właściwie zoptymalizować wszystkie te kwestie za Ciebie poprzez własną analizę kodu i specyfikację flag optymalizacji przekazanych do kompilatora. Jeśli zależy Ci na szybkości, powiedz kompilatorowi, aby zoptymalizował szybkość. Jeśli zależy ci na przestrzeni, powiedz kompilatorowi, aby zoptymalizował się pod kątem miejsca. Jak wspomniano w innej odpowiedzi, przyzwoity kompilator wstawi się automatycznie, jeśli naprawdę ma sens.
Ponadto, jak powiedzieli inni, użycie inline nie gwarantuje inline niczego. Jeśli chcesz to zagwarantować, będziesz musiał zdefiniować makro zamiast funkcji wbudowanej.
Kiedy wstawiać i / lub definiować makro, aby wymusić włączenie? - Tylko wtedy, gdy masz zademonstrowany i konieczny udowodniony wzrost prędkości dla krytycznej sekcji kodu, o której wiadomo, że ma wpływ na ogólną wydajność aplikacji.
źródło
Nie chodzi tylko o wydajność. Zarówno C ++, jak i C są używane do programowania osadzonego na sprzęcie. Jeśli chcesz na przykład napisać moduł obsługi przerwań, musisz upewnić się, że kod może zostać wykonany natychmiast, bez zamiany dodatkowych rejestrów i / lub stron pamięci. Właśnie wtedy przydaje się inline. Dobre kompilatory wykonują pewne „inliniowanie”, gdy potrzebna jest prędkość, ale „inline” je zmusza.
źródło
Wpadłem w ten sam problem z wstawianiem funkcji do bibliotek. Wygląda na to, że funkcje wbudowane nie są kompilowane w bibliotece. w wyniku tego linker zgłasza błąd „niezdefiniowane odwołanie”, jeśli plik wykonywalny chce użyć wbudowanej funkcji biblioteki. (przydarzyło mi się kompilowanie źródła Qt z gcc 4.5.
źródło
Dlaczego nie włączyć domyślnie wszystkich funkcji? Ponieważ jest to kompromis inżynieryjny. Istnieją co najmniej dwa rodzaje „optymalizacji”: przyspieszenie programu i zmniejszenie rozmiaru (powierzchni pamięci) programu. Inlining ogólnie przyspiesza. Pozbywa się narzutu wywołania funkcji, unikając pchania, a następnie wyciągania parametrów ze stosu. Jednak powoduje to również zwiększenie pamięci programu, ponieważ każde wywołanie funkcji musi teraz zostać zastąpione pełnym kodem funkcji. Aby jeszcze bardziej skomplikować sprawę, pamiętaj, że procesor przechowuje często używane fragmenty pamięci w pamięci podręcznej procesora, zapewniając ultra szybki dostęp. Jeśli sprawisz, że obraz pamięci programu będzie wystarczająco duży, Twój program nie będzie w stanie efektywnie wykorzystywać pamięci podręcznej, aw najgorszym przypadku wbudowanie może spowolnić program.
źródło
Nasz profesor informatyki namawiał nas, aby nigdy nie używać inline w programie c ++. Zapytany, dlaczego, uprzejmie wyjaśnił nam, że nowoczesne kompilatory powinny wykryć, kiedy automatycznie używać wbudowanego.
Tak, inline może być techniką optymalizacji, która może być stosowana wszędzie tam, gdzie jest to możliwe, ale najwyraźniej jest to już coś dla ciebie zrobione, ilekroć możliwe jest wstawienie funkcji w każdym razie.
źródło
inline
w C ++ ma dwa bardzo różne znaczenia - tylko jedno z nich jest związane z optymalizacją, a twój profesor ma rację w tym zakresie. Jednak drugie znaczenieinline
jest często konieczne, aby spełnić regułę jednej definicji .Wniosek z innej dyskusji tutaj:
Czy są jakieś wady związane z funkcjami wbudowanymi?
Najwyraźniej nie ma nic złego w korzystaniu z funkcji wbudowanych.
Warto jednak zwrócić uwagę na następujące punkty!
Nadużywanie wbudowania może spowolnić programy. W zależności od wielkości funkcji wstawianie jej może powodować zwiększenie lub zmniejszenie rozmiaru kodu. Wprowadzenie bardzo małej funkcji akcesorium zwykle zmniejsza rozmiar kodu, natomiast wprowadzenie bardzo dużej funkcji może radykalnie zwiększyć rozmiar kodu. Na nowoczesnych procesorach mniejszy kod zwykle działa szybciej ze względu na lepsze wykorzystanie pamięci podręcznej instrukcji. - Wytyczne Google
Korzyści prędkości funkcji wbudowanych zmniejszają się wraz ze wzrostem wielkości funkcji. W pewnym momencie narzut wywołania funkcji staje się niewielki w porównaniu do wykonania treści funkcji, a korzyść jest tracona - Źródło
Istnieje kilka sytuacji, w których funkcja wbudowana może nie działać:
Słowo
__inline
kluczowe powoduje wstawienie funkcji tylko wtedy, gdy podasz opcję optymalizacji. Jeśli określono optymalizację, to, czy ma__inline
być honorowana, zależy od ustawienia opcji optymalizatora wbudowanego. Domyślnie opcja wbudowana działa przy każdym uruchomieniu optymalizatora. Jeśli określisz optymalizację, musisz również określić opcję noinline, jeśli chcesz, aby__inline
słowo kluczowe było ignorowane. -Źródłoźródło
inline
słowo kluczowe przy ustalaniu, czy wstawić kod, czy wszystkie powyższe punkty są błędne. Byłyby prawdziwe, gdyby kompilator użył słowa kluczowego do wstawiania (służy on tylko do oznaczania zaznaczenia wielu definicji do celów łączenia).