Następna strona Poprzednia strona Spis treści

2. CZY POTRZEBUJESZ ASEMBLACJI?

No, nie chciałbym przeszkadzać w tym co robisz, ale tu jest kilka porad ciężko zarobionego doświadczenia.

2.1 Za i Przeciw

Korzyści Assemblacji

Assemblacja może wyrazić mocno niskopoziomowe rzeczy:

Niekorzyści Assemblacji

Assemblacja jest bardzo nisko-poziomowym językiem (najniższym jest ręczne-kodowanie w kodach binarnych instrukcji).

To znaczy

Ocenianie

Podsumowując, chociaż możesz uznać że użycie assemblacji jest czasami konieczne, a nawet pożyteczne w kilku przypadkach gdzie nie jest konieczne, będziesz chciał:

Nawet w przypadkach kiedy Assemblacja jest konieczna (np. rozwój OS) możesz uznać, że nie aż do tego stopnia i trzymać się w/w zasad.

Obejrzyj źrodła jądra Linux-a zwracając uwagę: jak mało assemblacji jest konieczne, by uzyskać szybki, niezawodny, przenośny, utrzymywalny OS. Także udana gra taka jak DOOM została prawie całkowicie napisana w C, z mała częścią napisaną w assemblerze tylko do przyśpieszenia jej działania.

2.2 Jak NIE używać Assemblera

Ogólne zasady uzyskania efektywnego kodu

Jak rzekł Charles Fiterman na comp.compilers o 'człowieku kontra kod assemblera wygenerowany przez komputer',

``Człowiek powinien zawsze wygrać i oto przyczyna.

Człowiek wygrywa poniewaz umie używać maszyny.''

Języki ze zoptymalizowanymi kompilatorami

Języki takie jak ObjectiveCAML, SML, CommonLISP, Scheme, ADA, Pascal, C, C++, wsród innych, wszystkie mają wolne zoptymalizowane kompilatory, które zoptymalizują masę twoich programów, i często będą lepsze niż ręczny kod assemblera nawet dla szczelnych pętli, umożliwiając ci skoncentrowanie się na wysokopoziomowych szczegółach, i bez zakazywania ci złapania kilku procent wykonania w wyżej wymieniony sposób w momencie gdy osiągniesz stabilny rozwój. Oczywiście, są także komercyjne zoptymalizowane kompilatory dla większości z tych języków.

Pewne języki mają kompilatory produkujące kod w C, który może być dalej zoptymalizowany przez dany kompilator C. Takimi są LIST, Scheme, Perl i wiele innych. Prędkość jest całkiem dobra.

Ogólne zasady przyśpieszania twojego kodu

W celu przyspieszenia kodu powinieneś robić zrobić to tylko dla fragmentów programu które narzędzie profilujące konsekwentnie określa jako wąskie gardło wykonania.

Stąd, jeśli określisz fragmenty kodu jako zbyt wolne, powinieneś

Na końcu, przed zejściem do pisania w assemblerze, powinieneś prześledzić wygenerowany kod, sprawdzając czy problem nie leży faktycznie w złej generacji kodu, co jest możliwe ale nie w wypadkach: kod wygenerowany przez kompilator może być lepszy niż mógłbyć napisać, w szczególności na nowoczesnych architekturach! Wolne części programu mogą być równie zagmatwane. Największym problemem nowoczesnych architektur z szybkimi procesorami są pewne opóźnienia dostępu do pamięci, nietrafiony dostęp do cache, i TLB oraz błędy stronnicowania; optymalizacja z użyciem rejestrów staje się wtedy mniej użyteczna, i zyskałbyć więcej po przemyśleniu struktury danych oraz wykorzystując wątkowanie gdyż uzyskałbyś lepsze umiejscowienie w dostępie do pamięci. Być może poźniej dopiero całkowicie odmienne spojrzenie na problem, pomoże go rozwiązać.

Sprawdzanie kodu generowanego przez kompilator

Jest wiele powodów do sprawdzenia kodu generowanego przez kompilator. Tu jest zawarte co robić z takim kodem:

Standardową metodą uzyskania kodu assemblera jest wywołanie twojego kompilatora z flagą -S. Działa to dla większości Unix-owych kompilatorów, włączając w to GNU C Compiler (GCC), ale YMMV. Dla GCC, bardziej zrozumiały kod assemblera będzie wyprodukowany po użyciu opcji -fverbose-asm. Oczywiście, jeśli chcesz dostać dobry kod assemblera, nie zapomnij użyć opcji optymalizacji i wskazówek!


Następna strona Poprzednia strona Spis treści