🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #310017

Re: Optymalizacja kodu

#310017
From: M.M.
Date: Thu, 26 Dec 2019 03:46
105 lines
6605 bytes
On Wednesday, December 25, 2019 at 10:49:29 PM UTC+1, Maciek Godek wrote:
> W dniu środa, 25 grudnia 2019 21:49:10 UTC+1 użytkownik M.M. napisał:
> > On Wednesday, December 25, 2019 at 8:52:44 PM UTC+1, Maciek Godek wrote:
> > > W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> > > > On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > > > > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > > > > 
> > > > > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > > > > 
> > > > > Zresztą nawet w C można to sobie zarytmetyzować:
> > > > > 
> > > > > int x = random() & odpowiednia_maska_bitowa;
> > > > > return x - (x > zakres)*(potęga_dwójki - zakres);
> > > > 
> > > > Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> > > > operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> > > > był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> > > > optymalizacje, ale na pewno mogą być.
> > > > 
> > > > Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> > > > zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> > > > szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> > > > eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> > > > dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> > > > 
> > > > T& operator()(const size_t i) {
> > > >   if( i >= SIZE ) abort();
> > > >   return data[i];
> > > > }
> > > > 
> > > > To działa o 10% szybciej niż gdy mam samo return:
> > > > 
> > > > T& operator()(const size_t i) {
> > > >   return data[i];
> > > > }
> > > > 
> > > > Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> > > > abort - wszak to wywołanie znamienne.
> > > 
> > > Ostatnio wrzucałem na pl.comp.programming linka do tej prezentacji:
> > > https://www.youtube.com/watch?v=r-TLSBdHe1A
> > > 
> > > Obczaj sobie narzędzia od tego gościa, bo może się okazać, że zmiana katalogu, z którego odpalasz program, będzie miała podobny wpływ na wydajność.
> > 
> > Chyba niemożliwe, zmiana katalogu może mieć 10-cio krotny wpływ na wydajność?
> 
> Wcześniej pisałeś, że o 10% szybciej

Pomiędzy wersją najszybszą a najwolniejszą mam 90% lub 1000% - zależy jak 
liczyć. Różnice pomiędzy wersją najszybszą a najwolniejszą są w moim odczuciu
kosmetyczne. NP. są wskaźniki zamiast indeksów:

return *i1++
zamiast
return buff[i1++]

Pamięć bufora jest pobierana z new, zamiast z pierwszego elementu tablicy:

buff = new typ[rozmiar];

zamiast

buff[rozmiar];
buff = &vector[0];

Jest minimalna optymalizacja instrukcji warunkowych.

Dziwi mnie przyspieszenie 10cio krotne z powodu takich niemal kosmetycznych
zmian.

Poza tym jest druga sprawa. Gdy dodaję kod, dokładnie gdy dodaję jedną
instrukcję warunkową:

if( index >= SIZE ) abort(); // Tak tę instrukcję.
return buff[index];

to program zaczął działać o 10% szybciej.

Ale... co ma wspólnego katalog z przyspieszeniem obliczeń na CPU? Swoją drogą,
odpalałem wszystkie testy z tego samego katalogu. 10% na czasie obliczeń
rzędu 100-200 sekund to chyba mierzalna wartość?

Kiedyś czytałem zdanie z którym nie do końca się zgadzam, że genialność języka
C i jego następcy C++ polega na tym, iż można kompilatorowi dzięki wskaźnikom
podpowiedzieć co ma być obliczane i kompilator generuje bardziej efektywny 
kod. Oczywiście w innych językach też można spotkać wskaźniki, a jeśli nie
ma wskaźników, to kompilator ma pewność że dane nie zostały zmienione za pomocą
dostępu przez wskaźniki  i może generować wydajniejszy kod. Przez wiele ostatnich
lat (około 10-12) widziałem, że drobne zmiany w kodzie nie wpływają na wydajność
obliczeń. Czy używałem wskaźnika, czy tablicy i indeksu, czy wektora, czy
makra, czy funkcji inline, czas był z reguły podobny, a nigdy nie był tak 
mocno różny. Ostatnio widzę że z powrotem dzięki kilku drobnym eksperymentom 
cały duży program można przyspieszyć np. dwa razy, a malutką procedurę nawet
10 razy. Co się stało? Używam kompilatora:

g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Pozdrawiam


Pozdrawiam
Technical Details
Message-ID: <bf2c2275-1ad9-497c-ac81-4d4ac227461b@googlegroups.com>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!feeder.erje.net!2.eu.feeder.erje.net!news.unit0.net!weretis.net!feeder7.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!g89no9012749qtd.0!news-out.google.com!w29ni69qtc.0!nntp.google.com!g89no9012746qtd.0!postnews.google.com!google-groups.googlegroups.com!not-for-mail
References: <ed3041b7-c05f-43f3-887a-9a12a9633741@googlegroups.com> <b010dc08-d015-4a47-88be-75fa3b91cd07@googlegroups.com> <c13192a2-18b8-4342-ad49-6a90cf36a636@googlegroups.com> <ffcbee1e-596b-4120-95ac-ac0d8d2d5e5d@googlegroups.com> <3f8cdd53-6885-4b7d-b87b-1d378ba3f319@googlegroups.com> <699dc753-f600-4656-a749-dca9be4d3668@googlegroups.com> <86e65a23-77b4-4037-930a-042ee5fb0bf3@googlegroups.com>

Show Full Headers
Complete Article Headers
X-Received: by 2002:a05:620a:1010:: with SMTP id z16mr36188917qkj.237.1577331979753;        Wed, 25 Dec 2019 19:46:19 -0800 (PST)
X-Received: by 2002:a5b:d0b:: with SMTP id y11mr15362579ybp.173.1577331979445; Wed, 25 Dec 2019 19:46:19 -0800 (PST)
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!feeder.erje.net!2.eu.feeder.erje.net!news.unit0.net!weretis.net!feeder7.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!g89no9012749qtd.0!news-out.google.com!w29ni69qtc.0!nntp.google.com!g89no9012746qtd.0!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: pl.comp.lang.c
Date: Wed, 25 Dec 2019 19:46:19 -0800 (PST)
In-Reply-To: <86e65a23-77b4-4037-930a-042ee5fb0bf3@googlegroups.com>
Complaints-To: groups-abuse@google.com
Injection-Info: google-groups.googlegroups.com; posting-host=77.254.46.242; posting-account=xjvq9QoAAAATMPC2X3btlHd_LkaJo_rj
NNTP-Posting-Host: 77.254.46.242
References: <ed3041b7-c05f-43f3-887a-9a12a9633741@googlegroups.com> <b010dc08-d015-4a47-88be-75fa3b91cd07@googlegroups.com> <c13192a2-18b8-4342-ad49-6a90cf36a636@googlegroups.com> <ffcbee1e-596b-4120-95ac-ac0d8d2d5e5d@googlegroups.com> <3f8cdd53-6885-4b7d-b87b-1d378ba3f319@googlegroups.com> <699dc753-f600-4656-a749-dca9be4d3668@googlegroups.com> <86e65a23-77b4-4037-930a-042ee5fb0bf3@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <bf2c2275-1ad9-497c-ac81-4d4ac227461b@googlegroups.com>
Subject: Re: Optymalizacja kodu
From: "M.M." <mmarszik@gmail.com>
Injection-Date: Thu, 26 Dec 2019 03:46:19 +0000
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit