Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Czasy wykonania instrukcji - C++

Lumberjack 20 Sty 2011 17:56 1115 4
  • #1 20 Sty 2011 17:56
    Lumberjack
    Poziom 10  

    Witam
    Interesuje mnie sprawa czasów wykonywania się instrukcji w języku C++. Instrukcji np. Warunkowej if , inkrementacji , dekrementacji , warunku while itd. W zasadzie interesuje mnie liczba cykli maszynowych koniecznych do wykonania tych instrukcij i nie tylko tych (chcialbym uzyskać jak najwiecej informacji). Gdzie mogłbym znaleźć takie informacje w sieci? Pozdrawiam

    0 4
  • #2 20 Sty 2011 18:43
    kubatek94
    Poziom 17  

    Wydaje mi sie ze piszesz jakis prosty program (z wykorzystaniem ktorys z tych instrukcji) i po skompilowaniu wrzucasz go do disassemblera i sprawdzasz ile instrukcji jest do wykonania.

    Pozdrawiam

    0
  • #3 20 Sty 2011 19:35
    Lumberjack
    Poziom 10  

    Nie pisze programu. Chciałby sie dowiedzieć czasy wykonania instrukcji w zależności od cykli zegara. Np. ile cykli zegarowych potrzeba na wykonanie instrukcji warunkowej lub warunku while , instrukcji switch itp. gdzie moge znależź takie informacje?

    0
  • #4 20 Sty 2011 19:50
    kubatek94
    Poziom 17  

    Nie zrozumiales mnie, ale nie wazne. Wszystko zalezy od Twojego procesora- znajdz datasheeta swojego cpu i zobacz ile typowo (bo wszystko zalezy od roznych czynnikow) wykonuja sie instrukcje (oczywiscie beda podane instrukcje assemblera). Teraz co musisz zrobic- napisz jakis prosty kod ktory wykorzystuje zadana instrukcje (if, while etc) i niech kompilator "wypluje" kod assemblera. Tutaj bedziesz widzial jak taka instrukcja w C wyglada w assemblerze i jakie instrukcje sa wykonywane w assemblerowym kodzie.

    Pozdrawiam

    0
  • #5 21 Sty 2011 10:02
    MirekCz
    Poziom 35  

    Nie dowiesz się tego.
    Zależy to od warunku (co innego jest porównanie liczb zmiennoprzecinkowych, co innego stałoprzecinkowych, co innego liczb które pobiera z jakiejś struktury/klasy itd itd itd) jak i tego co wykonuje się dookoła tego warunku (np. czy dane są w pamięci czy musi je ściągnąć z niej).
    Nie ma sensu analizowanie poszczególnych linijek kodu pod względem ew. prędkości. Musisz analizować cały kod. Do tego celu służy tzw. profiler. Są też specjalne narzędzia np. intela, które bardzo ułatwiają optymalizację kodu. Po użyciu profilera możesz się np. dowiedzieć która funkcja ile razy jest wykonywana i ile % czasu wykonywania całego programu zajmuje. Pozwala to szybko oszacować którą część kodu warto optymalizować.
    Jak potrzebujesz maksymalnie coś zoptymalizować to najlepiej zobaczyć jaki kod wyprodukował kompilator (listing kodu z kompilatora z kodem assemblera) i ew. napisać to samemu w assemblerze. Chociaż czasami taki listing wystarczy żeby zmienić w kodzie wysokiego poziomu kilka linijek i uzyskać lepszy kod automatycznie wygenerowany przez kompilator.

    Jak interesują Ciebie konkretne informacje ile wykonują się poszczególne operacje w assemblerze to musisz spojrzeć w dokumentację procesora. Każdy procesor nawet tej samej firmy może mieć poważne różnice w wykonywaniu poszczególnych instrukcji. Do tego są jeszcze przynajmniej dwie ważne kwestie wpływające na wykonywanie programu:
    - obecne procesory mają długi pipeline - jedna instrukcja wykonuje się w kilkunastu krokach. Jeżeli jedna instrukcja np. zmienia wartość rejestru, a następna instrukcja z tego rejestru korzysta to musi czekać aż poprzednia instrukcja przejdzie ileś kroków. Tak samo jak masz instrukcję warunkową to może się okazać, że warunek zwrócił inny wynik niż on założył i cały pipeline jest do "śmieci", bo wszystkie kolejne instrukcje które zaczął przygotowywać do wykonania nie zostaną wykonane.
    - bardzo długi jest czas dostępu procesora do pamięci. Dlatego masz teraz cache kilku poziomów (zazwyczaj 1, 2 a czasem w wieluprocesorowych też 3). Czym potrzebna dana jest dalej od procesora tym wielokrotnie zwiększa się czas jej ściągnięcia. Odpowiednie napisanie programu żeby nie zaśmiecać pamięci cache może mieć ogromne znaczenie dla szybkości wykonywania się instrukcji. Czasami dużo szybsze jest wykonywanie jakiejś skomplikowanej operacji matematycznej zamiast trzymanie gotowego wyniku w dużej tablicy, bo ciągły dostęp do dużej tablicy "zawala" pamięć cache jej danymi i procesor stale musi korzystać z pamięci głównej dla innych danych co może trwać kilkaset cykli zegara.

    Ogólnie to o co Ty pytasz to bardzo skomplikowana sprawa w nowoczesnych procesorach i nie da się tego w prosty sposób policzyć. Najczęściej używa się profilerów i/lub dokładnych zegarów do mierzenia czasu wykonywania jakiejś funkcji / części programu i wg. tego się optymalizuje kod w języku wysokiego-poziomu. Assemblera używa się już rzadko.

    0