Autor Wątek: [c++] Pytania optymalizacyjne. (obiektowość).  (Przeczytany 990 razy)

Offline Bloodian

  • Użytkownik

# Kwiecień 01, 2012, 22:14:26
Witam.
Gryzie mnie parę pytań dotyczących obiektowości w C++.

1) Czy metody których ciała są wpisane bezpośrednio w klasie są automatycznie inline ? Żeby metoda byłe nie-inline trzeba stworzyć jej prototyp, a później poza klasą wypełnić ciałem ? Jeżeli tak to dlaczego ?

2)edit : racja, mój błąd. Źle przeczytałem. edit2: Asmen odpowiedział to wklejam pytanie


 Czytam sobie megatutorial i jest tu rozdział o tym jak wykonane jest dziedziczenie. Wynika z tego że jeżeli w klasie bazowej zrobimy np. pole int X i stworzymy klasę która dziedziczy od tej klasy, np. A to tworząc obiekt A, na stercie tak naprawdę mamy dwa pola X. Idąc tą myślą załóżmy że nasza klasa X jest megagigantyczna i ma dziesiątki tysięcy danych. Oznacza to że jeżeli stworzymy małe drzewo typu X->A->B->C->D to te wszystkie dane stworzą się 5 razy ?


3) Podobne pytanie, ale jeżeli chodzi o metody klasy/funkcje globalne. Czy jeżeli napiszę sobie np. z 10000 funkcji, a mój program użyje tylko jednej z nich to czy te wszystkie funkcje i tak zostaną załadowane do pamięci ?

Dzięki :)
« Ostatnia zmiana: Kwiecień 01, 2012, 22:33:29 wysłana przez Bloodian »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline mihu

  • Użytkownik
    • mihu

# Kwiecień 01, 2012, 22:19:58
2) Chyba musisz przeczytać jeszcze raz. :)

Offline MaxGarden

  • Użytkownik
    • Profil na warsztacie

# Kwiecień 01, 2012, 22:26:49
Od kiedy to funkcje mają rozmiar (nie licząc ofc zmiennych lokalnych w funkcji, ale i tak bez wywołania nie zaalokują pamięci) ?

Offline asmen

  • Użytkownik

# Kwiecień 01, 2012, 22:27:21
1. Tak, funkcje implementowane wewnątrz klasy są traktowane jako inline. Dlaczego? Tego aktualnie nie pamiętam, poszukaj.
2. Nie to byłoby bez sensu. Jeśli tworzysz obiekt klasy dziedziczący po klasie bazowej. To wewnątrz niego masz dostępną tylko jedną metodę x.
3. Wydaje mi się, że tak, ponieważ ładowany do pamięci jest obiekt, a nie jego pojedyncze elementy. Chyba, że kompilator robi coś automagicznie ;)

Offline hashedone

  • Użytkownik

# Kwiecień 01, 2012, 22:34:03
Z inliningiem może być różne. Przede wszystkim nawet pisząc przed funkcją inline nie gwarantuje, że zostanie inlinowana. Może być to potraktowane najwyżej jako wskazówka dla kompilatora. Pytania 2 nie znam, więc nie odpowiadam. Co do 3 - na cholerę? Usuwanie nieużywanych symboli to podstawowa optymalizacja którą przeprowadzają prawdopodobnie wszystkie współczesne kompilatory.
@MaxGarden - odkąd istnieją kompilatory. Każda op procesora ma jakiś rozmiar. Funkcja to tylko zbiór opów.

Offline koirat

  • Użytkownik

# Kwiecień 01, 2012, 22:42:17
1. @asmen jesteś pewien. Z tego co mi wiadomo nie możemy być pewni czy funkcja zostanie zinlinowana czy nie nawet jak wstawimy słowo kluczowe "inline".  "hashedone był szybszy :)"

2. @Bloodian może chodziło ci o sytuacje zwaną "Diamond problem"

3. Nie dam sobie nic uciąć ale to może zależeć od poziomu optymalizacji. Jeśli masz włączoną optymalizacje to są one usuwane. Zresztą czasem są usuwane nawet funkcje oraz kawałki kodu użyte które kompilator uznał za nie mające wpływu na działanie. Przykładem może być pętla w której nic się nie dzieje albo funkcja która nic nie robi.

Offline Bloodian

  • Użytkownik

# Kwiecień 01, 2012, 22:57:44
Dzięki wielkie.

"Diamon problem" - popatrzę sobie.

Offline asmen

  • Użytkownik

# Kwiecień 01, 2012, 22:59:01
@up up tak, nie możemy być pewni, że kompilator to zinlinuje(ale spolszczenie :D), ale powinien, a to co robi to już jego sprawa ;). Co do punktu 3 to mieliśmy tu kiedyś takiego gościa, który napisał dwie takie same funkcje, które nic nie robiły i dziwił się, że kompilator zostawił jedną ;)

Offline Xirdus

  • Moderator

# Kwiecień 01, 2012, 23:16:29
zinlinuje(ale spolszczenie :D)
Poprawnie powinno być "zinline'uje".

ale powinien
Nikt mu nie nakazuje. Dosłownie tak jest w standardzie.

Offline asmen

  • Użytkownik

# Kwiecień 01, 2012, 23:27:05
Poprawnie powinno być "zinline'uje".
Wiem, ale tak jest bardziej pr0 :)

Offline bies

  • Użytkownik

# Kwiecień 02, 2012, 00:17:49
Co do funkcji kompilator może je pominąć tylko wtedy gdy:
- są prywatne w jednostce translacji (namespace {}); lub
- kompilator wie, że kompiluje program więc może usunąć symbole zewnętrze.
Linker może takie funkcje usunąć przy linkowaniu exe natomiast nie usunie ich przy linkowaniu dll.

Co do pamięci: to nie jest tak, że wszystkie funkcje zapisane w programie muszą od razu być czytane do pamięci. Jeśli od main() do nieużywanej funkcji jest odpowiednio daleko (przynajmniej jedna strona pamięci) to system może zostawić taki kod nieprzeczytany na dysku do momentu pierwszego użycia czegoś z owej strony. Nie wiem czy akurat Windows tak działa (powinien).
« Ostatnia zmiana: Kwiecień 02, 2012, 00:40:19 wysłana przez bies »

Offline Aithne

  • Użytkownik

# Kwiecień 02, 2012, 11:22:01
Linker może takie funkcje usunąć przy linkowaniu exe natomiast nie usunie ich przy linkowaniu dll.
Wtedy też może, przecież wie, co jest eksportowane (dllexport/visibility("default")), a co nie jest ;)