-
81. Data: 2009-05-19 22:36:41
Temat: Re: jak napisać szybki program
Od: A.L. <a...@a...com>
On Tue, 19 May 2009 15:12:50 -0700 (PDT), Marteno Rodia
<m...@o...pl> wrote:
>On May 19, 11:48 am, "Mateusz Loskot" <m...@l...net> wrote:
>> > albo co jest szybsze: int array[10] czy int *array = new int[10].
>>
>> Pierwsze to alokacja na stosie, drugie na tzw. stercie (dynamic storage)
>> Ogólna zasada przy optymalizacji, to im mniej alokacji pamięci
>> tym lepiej. Alokacja to wolna operacja.
>
>To co zrobić, żeby unikać konstrukcji spowalniających program? Pamięci
>muszę używać, a żeby używać - muszę chyba jakoś ją zaalokować.
>
>MR
Znasz bajeczke o stonodze?... "Stonoga" - taki robak co ma 100 nog
A.L.
-
82. Data: 2009-05-19 22:38:27
Temat: Re: jak napisać szybki program
Od: Mateusz Loskot <s...@s...net>
Marteno Rodia wrote:
> On May 19, 11:48 am, "Mateusz Loskot" <m...@l...net> wrote:
>>> albo co jest szybsze: int array[10] czy int *array = new int[10].
>>
>> Pierwsze to alokacja na stosie, drugie na tzw. stercie (dynamic storage)
>> Ogólna zasada przy optymalizacji, to im mniej alokacji pamięci
>> tym lepiej. Alokacja to wolna operacja.
>
> To co zrobić, żeby unikać konstrukcji spowalniających program? Pamięci
> muszę używać, a żeby używać - muszę chyba jakoś ją zaalokować.
Możesz poprosić o to kompilator, nie koniecznie system operacyjny.
Poczytaj tu:
http://en.wikipedia.org/wiki/C_(programming_language
)#Memory_management
Pozdrawiam,
--
Mateusz Loskot, http://mateusz.loskot.net
Charter Member of OSGeo, http://osgeo.org
-
83. Data: 2009-05-20 08:55:46
Temat: Re: jak napisać szybki program
Od: Maciej Sobczak <s...@g...com>
On 19 Maj, 23:08, Michoo <m...@v...pl> wrote:
> > char my_buffer[my_size];
>
> > Niezależnie od metody dane muszą być przetransferowane z/do my_buffer.
>
> W przypadku dobrej implementacji (na gruncie czystej teorii - nie chce
> mi się teraz zastanawiać gdzie to jak jest zaimplementowane - chodzi mi
> o sam fakt, że jest to jedyny zysk jaki można osiągnąć) i/o kopiowanie
> danych na drodze dysk->ram, bufor karty sieciowej-> ram, etc powinno być
> robione "na zewnątrz" procesora (i to w trybie nie odcinającym go od szyny).
Tak i jest to możliwe zarówno przy synchronicznym jak i
asynchronicznym I/O.
Różnica między nimi jest tylko w tym, że pierwszy czeka na zakończenie
procesu a drugi jest "powiadamiany".
Oczywiście można sobie też wyobrazić, że w jednym z przypadków system
korzysta z dodatkowych buforów i wykonuje dodatkowe kopie danych, ale
to jest kwestia jakości implementacji i nie ma związku z samym
aspektem synchro/asynchro.
Dlatego nie ma sensu twierdzić, że AIO daje jakiś zysk w kontekście
zarządzania buforami.
> synchroniczne i/o: program robi wywołanie systemowe "czytaj" system
> wywala wątek z kolejki procesów gotowych i zleca kontrolerowi transfer,
> po otrzymaniu przerwania od kontrolera proces wraca do kolejki i w
> najbliższym czasie wraca z wywołania
Tak.
> asynchroniczne i/o: program robi wywołanie systemowe "czytaj" system
> zleca kontrolerowi transfer, wątek powraca z wywołania i może pracować.
> po otrzymaniu przerwania od kontrolera system powiadamia wątek o
> zakończeniu operacji.
To duży skrót myślowy [*], ale przyjmijmy roboczo, że tak jest.
Trwa to dokładnie tyle samo (bo dysk się kręci tak samo szybko).
[*] Skrót myślowy polega na tym, że w językach sekwencyjnych nie ma
czegoś takiego jak "powiadamianie wątku". Są dwa możliwe mechanizmy:
1. Sygnalizacja (notify) jakiegoś wskazanego obiektu
synchronizacyjnego. Pozwala to właściwym wątkom roboczym zorientować
się (blokująco bądź nie), że operacja się zakończyła.
2. Wywołanie przez callback - to wywołanie odbywa się w *innym* wątku,
z osobnym stosem, przynajmniej koncepcyjnie (tu wliczamy wszystko od
sygnałów w C po AsyncHandler w Javie). Zwykle jedyna rzecz jaką można
w takim callbacku sensownie zrobić to... ręcznie punkt 1.
To żadna magia, dlatego też w ostatecznym rozrachunku SIO i AIO
mogą robić to samo, z dokładnością do ilości *śpiących* wątków
userlandu. W szczególności istnieją implementacje, które robią SIO
jako nakładkę (!) na AIO albo odwrotnie. To właśnie sprawia, że AIO
nie jest cudownym rozwiązaniem a ponieważ jest intruzywne i słabo
komponowalne (nie da się go zastosować do *istniejącego* kodu), to
powinno być stosowane... ostrożnie.
> W drugim przypadku wątek może pracować w trakcie kopiowania danych.
Czyli cały czas mówimy o użyciu współbieżności w celu lepszego
wykorzystania zasobów sprzętowych. Powtórzę: to nie jest wyłączna
cecha AIO. Współbieżność jest narzędziem bardziej ogólnym.
--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
-
84. Data: 2009-05-20 12:32:13
Temat: Re: jak napisać szybki program
Od: A.L. <a...@a...com>
On Wed, 20 May 2009 01:55:46 -0700 (PDT), Maciej Sobczak
<s...@g...com> wrote:
>On
>
>Czyli cały czas mówimy o użyciu współbieżności w celu lepszego
>wykorzystania zasobów sprzętowych. Powtórzę: to nie jest wyłączna
>cecha AIO. Współbieżność jest narzędziem bardziej ogólnym.
.. i uzycie jej nie gwarantuje automatycznie poprawienia sprawnosci...
http://www.ddj.com/go-parallel/article/showArticle.j
html?articleID=217500206
A.L.
-
85. Data: 2009-05-20 17:44:43
Temat: Re: jak napisać szybki program
Od: Marteno Rodia <m...@o...pl>
> > albo co jest szybsze: int array[10] czy int *array = new int[10].
>
> Pierwsze to alokacja na stosie, drugie na tzw. stercie (dynamic storage)
> Ogólna zasada przy optymalizacji, to im mniej alokacji pamięci
> tym lepiej. Alokacja to wolna operacja.
Super. To teraz inne pytanie: jakie są (relatywnie szybkie w wykonaniu
czy raczej wolne) operacje dostępu do bitów?
Innymi słowy: potrzebuję przechować 100 trójek liczb całkowitych (a,
b, c), ale niewielkich, np. na a i b wystarczy po 12 bitow, a na c - 8
bitów. Te 3 liczby są jakoś semantycznie związane, więc warto, żeby
były "w kupie". Co jest szybsze?
a) używanie struktury
struct Tripple { int a; int b; int c}
olewając jednocześnie marnotrawstwo pamięci.
b) używanie struktury j.w. ale z typami short
c) używanie jednego integera do zapisu 3 liczb na różnych jego bitach
(2*12+8=32), tak że:
a = (liczby >>20) & 0xFF;
b = (liczby >> 8) & 0xFF;
c = liczby & 0xFF;
Co byście proponowali?
MR
-
86. Data: 2009-05-20 18:23:51
Temat: Re: jak napisać szybki program
Od: Michoo <m...@v...pl>
Marteno Rodia pisze:
>>> albo co jest szybsze: int array[10] czy int *array = new int[10].
>> Pierwsze to alokacja na stosie, drugie na tzw. stercie (dynamic storage)
>> Ogólna zasada przy optymalizacji, to im mniej alokacji pamięci
>> tym lepiej. Alokacja to wolna operacja.
>
> Super. To teraz inne pytanie: jakie są (relatywnie szybkie w wykonaniu
> czy raczej wolne) operacje dostępu do bitów?
>
> Innymi słowy: potrzebuję przechować 100 trójek liczb całkowitych (a,
> b, c), ale niewielkich, np. na a i b wystarczy po 12 bitow, a na c - 8
> bitów. Te 3 liczby są jakoś semantycznie związane, więc warto, żeby
> były "w kupie". Co jest szybsze?
Co sprawdzasz? - to jest ważne.
>
> a) używanie struktury
> struct Tripple { int a; int b; int c}
> olewając jednocześnie marnotrawstwo pamięci.
przy dobrych lotach na ia32 da to 3 instrukcje procesora[*] na
załadowanie adresów, 3 na pobranie do rejestrów, 3 na porównania i 3 na
zadecydowanie jaki branch
od poprzedniego punktu - jakie operacje.
lub 2 na pobranie, 1 na porównanie i 1 na branch (ze wsparciem sse, czy
czegoś takiego)
>
> b) używanie struktury j.w. ale z typami short
jak wyżej, ale jest szansa, że wszystkie 3 wartości polecą w jednym
odwołaniu do pamięci, albo, że b będzie "trawiona dłużej" bo po pobraniu
32 bitowego słowa procesor zrobi przesunięcie o 16 bitów żeby ja
dostać. Może się też nic nie zmienić, ale zaoszczędzisz miejsce w cache,
co da pewne przyspieszenie.
>
> c) używanie jednego integera do zapisu 3 liczb na różnych jego bitach
> (2*12+8=32), tak że:
> a = (liczby >>20) & 0xFF;
> b = (liczby >> 8) & 0xFF;
> c = liczby & 0xFF;
To by miało szansę być najszybsze pod warunkiem, że testujesz tylko
równość/różność a operacje "pakowania/rozpakowania" przeprowadzasz
rzadko. Jakby zdefiniować metody do wygodnego operowania na tych
składowych (a(),b(),c(), operator==) to byłoby to nawet względnie wygodne.
Główna wada to komplikacja - popełniłeś błąd, którego szukałbyś raczej
długo. Trzeba mieć dobry powód, żeby musieć tak kombinować.
>
> Co byście proponowali?
"jaka architektura?" - co innego będzie szybsze na avr, co innego na
arm9 a co innego na amd64. "jakie operacje?"
[*] a to ile cykli zegara zabiera 1 instrukcja to już ina bajka
--
Pozdrawiam
Michoo
-
87. Data: 2009-05-20 18:31:11
Temat: Re: jak napisać szybki program
Od: "Marcin 'Qrczak' Kowalczyk" <q...@k...org.pl>
On 20 Maj, 19:44, Marteno Rodia <m...@o...pl> wrote:
> a) używanie struktury
> struct Tripple { int a; int b; int c}
> olewając jednocześnie marnotrawstwo pamięci.
>
> b) używanie struktury j.w. ale z typami short
>
> c) używanie jednego integera do zapisu 3 liczb na różnych jego bitach
> (2*12+8=32), tak że:
> a = (liczby >>20) & 0xFF;
> b = (liczby >> 8) & 0xFF;
> c = liczby & 0xFF;
d) struct Triple { unsigned a : 12; unsigned b : 12; unsigned c :
8; };
W ten sposób zapis źródłowy będzie jaki w (a) czy (b), a wygenerowany
kod taki jak w (c).
Warto się w to bawić tylko jeśli tych trójek jest dużo.
-
88. Data: 2009-05-21 02:23:02
Temat: Re: jak napisać szybki program
Od: "Mariusz Marszałkowski" <b...@W...gazeta.pl>
Marteno Rodia <m...@o...pl> napisał(a):
Np. te dwie lektury:
Procesory Pentium - Michael L. Schmit
Optymalizacja Kodu - Kris Kaspersky
I z rok albo dwa doświadczenia jako koder
Pzdr
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
89. Data: 2009-05-21 03:26:02
Temat: Re: jak napisać szybki program
Od: "Mariusz Marszałkowski" <b...@W...gazeta.pl>
Jędrzej Dudkiewicz <j...@g...com> napisał(a):
> bartekLTG wrote:
> > Maciej Pilichowski wrote:
> >> aby zawsze pisac ++var zamiast
> >> var++ (o ile merytorycznie nie zachodzi koniecznosc tego drugiego),
> >
> > Im dluzej o tym mysle, tym bardziej nie rozumiem, o co Ci mogło chodzic;-)
>
> O ile pamiętam "rationale", to w C++ do iteracji winien być używany
> iterator. Będący obiektem, potencjalnie dużym i skomplikowanym. Kiedy w
> kodzie pojawia się "var++", w to miejsce należy zwrócić "starą" wartość
> var, a następnie zaaplikować operator++ na var, kiedy pojawia się ++var,
> nie trzeba zwracać kopii.
>
> JD
Może tak jest wydajniej, ale czy to nie jest pomylenie idei? Język C++
względem C i asemblera, zdecydowanie lepiej nadaje się do zarządzania
dużymi projektami i do ponownego wykorzystania kodu. Dzięki temu
jest optymalizowane co innego - czas i nakład ludzkiej pracy. Po co
używać języka wysokopoziomowego i jednocześnie wnikać w niuanse kompilacji?
W C++ pisze się na przeciążonych obiektach a = b + c dlatego żeby
ułatwić sobie życie, a nie dlatego że a = c + b jest mniej wydajnie.
Jeśli ktoś chce wydajnie zapisać program to musi użyć języka C i/albo
asemblera. Języki te mają to do siebie, że ich kompilatory nie wstawiają
do kodu wynikowego żadnych ukrytych wstawek. Kompilator wygeneruje to
co napiszesz.
Warto pamiętać że optymalizowanie zapisu może przyspieszyć program
co najwyżej liniowo. Zoptymalizowany w ten sposób program może
działać szybciej, ale jednocześnie przestaje być podatny na modyfikacje.
Jeśli po pewnym czasie pracy nad programem przychodzi pomysły na
modyfikację algorytmu, która może przyspieszyć więcej niż dobre
zakodowanie, to prawdopodobnie będzie trzeba napisać wszystko od nowa.
Twierdzę to w oparciu o doświadczenia jakie zdobyłem pisząc program do
gry w szachy - optymalizowałem go na oba sposoby około roku czasu.
Jeśli bym mógł wrócić do programowania szachów, nigdy więcej bym programu
nie zoptymalizował pod względem zapisu.
Ale jeśli ktoś nadal chce optymalizować zapis, to polecam dwie lektury:
- Optymalizacja Kodu - Kris Kaspersky
- Procesory Pentium - Michael L. Schmit
Pzdr
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
90. Data: 2009-05-21 03:51:46
Temat: Re: jak napisać szybki program
Od: "Mariusz Marszałkowski" <b...@W...gazeta.pl>
Marteno Rodia <m...@o...pl> napisał(a):
> On May 19, 11:48=A0am, "Mateusz Loskot" <m...@l...net> wrote:
> > > albo co jest szybsze: int array[10] czy int *array =3D new int[10].
> >
> > Pierwsze to alokacja na stosie, drugie na tzw. stercie (dynamic storage)
> > Og=F3lna zasada przy optymalizacji, to im mniej alokacji pami=EAci
> > tym lepiej. Alokacja to wolna operacja.
>
> To co zrobi=E6, =BFeby unika=E6 konstrukcji spowalniaj=B1cych program? Pami=
> =EAci
> musz=EA u=BFywa=E6, a =BFeby u=BFywa=E6 - musz=EA chyba jako=B6 j=B1 zaalok=
> owa=E6.
Najpierw poznaj dobrze język programowania, później nabierz w nim wprawy.
Wymyśl codziennie jakieś zadanie i je rozwiązuj, po kilku miesiącach
będziesz miał wyczucie. Będziesz wiedział w jakim miejscu użycie new
znacznie spowolni Twój program.
Zamiast zastanawiać się jak napisać wydajnie 100 iteracji w których masz
dodać 100 liczb, lepiej zastanów się czy nie da się przewidzieć ich średniej
arytmetycznej i obliczyć sumę w jednej "iteracji" - to jest optymalizacja.
Pzdr.
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/