Wstawki asemblerowe w C++

Wstawki asemblerowe w C++
MI
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:85
0

Czy wstawki asemblera dodane do kodu w aplikacji napisanej natywnie w C++ dają jakieś realne benefity w wydajności aplikacji? Czy nauka asemblera np. 64 bitewnego w wydaniu MASM ma sens w 2020r. ? Czy też obecne kompilatory c++ są bardziej wydajne w takich zastosowaniach ?

edytowany 1x, ostatnio: Mirai
Szalony Programista
Szalony Programista
  • Rejestracja:około 7 lat
  • Ostatnio:prawie 4 lata
  • Postów:227
1

Nie ma sensu dodawać assemblera do własnego kodu.
Asembler się przydaje do analizowania binarek, nie mając dostępu do kodu wysokopoziomowego.

Wszystko co w assemblerze możesz też w c/c++ zrobić i na odwrót, tyle że wymaga to większego nakładu pracy.
Assembler przydaje się przy manipulowaniu w nie swoich programach.

Ale assembler jest się dobrze nauczyć, później można się pobawić w memory forensics.
Znajdywać określone metody, struktury w procesach, debuggować, wykonywać binary exploitation.

Przy thread hijacking lub dll injection musisz znaleźć adresy danych struktur, funkcji, które potem możesz kodem w C/C++ manipulować lub dodawać swoje operacje.
Ale żeby w kilku gigabajtach się odnaleźć, trzeba znać assemblera i sposoby odnalezienia się w gąszczu, bo przecież nie przeanalizujesz całego kodu :>

katakrowa
Coś tam ci świta o czymś masz pojęcie ale chyba nie na tyle by wyciągać tak ogólne wnioski.
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 2 godziny
3

Ale assembler jest się dobrze nauczyć

A żeby się nauczyć to trzeba trochę pokodzić, a nie tylko przejrzeć listę instrukcji…

Co do „wstawek” to jestem raczej przeciwnikiem robienia wstawek asemblerowych wewnątrz pliku .c czy .cpp.
Jak asembler to w osobnym pliku .asm, osobno skompilowanym i zlinkowanym z wysokopoziomową resztą programu (o ile taka jest).

dają jakieś realne benefity w wydajności aplikacji?

Wiedzę warto mieć; nie trzeba od razu wszystkiego sprowadzać do wydajności.

asemblera np. 64 bitewnego

Hmmm....

edytowany 2x, ostatnio: Azarien
katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
1
Szalony Programista napisał(a):

Nie ma sensu dodawać assemblera do własnego kodu.

Nie mogę się zgodzić bo to zwyczajnie nieprawda. Oczywiście należy liczyć się z wieloma negatywnymi konsekwencjami takiego postępowania jednak wstawki assemblerowe to bardzo dobre rozwiązanie przy wielu optymalizacjach. Nie jest też prawdą to, że to samo co uzyskasz w assemblerze także uzyskasz w c/c++.
Niejednokrotnie zoptymalizowanie wrażliwego kodu, który wykonywany jest w pętli ( lub całej kluczowej pętli ) miliony razy może finalnie przyspieszyć działanie programu nawet kilkukrotnie.
Żaden kompilator ( nawet te na AVR'y ) nie zoptymalizuje kodu tak dobrze jak doświadczony programista znający assembler.

Zresztą wystarczy zerknąć w debugger z podglądem ASM żeby na własne oczy zobaczyć jak wiele można zoptymalizować przy pętlach przenosząc zmienne do rejestrów, warunki optymalizując na odpowiednie uwarunkowania ze skokami, układając operacje w taki sposób by wykorzystać przetwarzanie potokowe pozwalając tym samym na wykonywanie dwóch instrukcji w jednym takcie.
Do tego dochodzi jeszcze wiele innych optymalizacji, których realizacja jest zwyczajnie niemożliwa korzystając z kompilatora języka wysokiego poziomu...


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
edytowany 2x, ostatnio: katakrowa
Szalony Programista
Szalony Programista
W C da się wygenerować dowolny kod assemblera, chodź czasem kompilator może zrobić coś po swojemu. Nie widzę przeszkód w dodawania assemblera, ale ja np. go nie stosuję po za nieoficjalnym kodem.
katakrowa
Bo widać nie rozumiesz do czego to służy.
Szalony Programista
Szalony Programista
Dziękuje za wytłumaczenie.
katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
0

Odpowiadając na "W C da się wygenerować dowolny kod assemblera, chodź czasem kompilator może zrobić coś po swojemu.".

Właśnie chodzi o to, że "czasem kompilator może zrobić coś po swojemu" a różnice w czasie wykonywania kodu optymalnego względem skompilowanego mogą być ogromne.
Oczywiście wskazane jest podejście takie jak proponuje @Azarien ale czasem zwyczajnie łatwiej zrobić to "wstawką".


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
edytowany 1x, ostatnio: katakrowa
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około godziny
  • Postów:4928
1

Jednak da się coś zoptymalizować pisząc moduły w Assemblerze, np. w SciPy i pandas jest go trochę (ok. 5%). Tu:
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-172-performance-engineering-of-software-systems-fall-2018/lecture-videos/
fajny kursik w temacie.


several
  • Rejestracja:prawie 16 lat
  • Ostatnio:2 minuty
1

Nie opłaca się używać wstawek asm do zastosowań ogólnych. Chyba, że potrzebujesz zoptymalizować bardzo specyficzną operację, na tyle specyficzną, że sam wiesz, że wskawka jest najlepszym wyjściem i nie musisz się radzić forum.


PerlMonk
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa 🐪
  • Postów:1719
3
katakrowa napisał(a):

Żaden kompilator ( nawet te na AVR'y ) nie zoptymalizuje kodu tak dobrze jak doświadczony programista znający assembler.

<ironia>Fajny truizm.</ironia>

W "dzisiejszych czasach" wstawki asemblerowe rzadko kiedy dają wymierne korzyści. Lata rozwoju informatyki dały nam algorytmy i języki wysokiego poziomu a kompilatory mają dobre (może nie idealne) możliwości optymalizacji pod sprzęt. Czy warto poświęcać kilka(naście) godzin na wstawkę w imię kilku procent? Znam przynajmniej kilku dyrektorów w większych firmach, którzy wyśmieją dupą każdego programistę, który walczy o megaherce.
Odpowiadam: warto znać konsekwencje swojej działalności, ale nie warto drzeć szat o każdy cykl - chociaż czasem kobiety to robią.


Nie sztuka uciec gdy w dupie sztuciec. 🐪🐪🐪
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około godziny
  • Postów:4928
0

ale nie warto drzeć szat o każdy cykl

Chyba, że Piszesz gry wideo.


Delor
... działające na jednym, konkretnym typie procesora. Konsole?
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 2 godziny
0

Asembler bywa potrzebny kiedy chcemy wykorzystać jakieś fancy instrukcje typu AVX, których nam kompilator C++ nie wypluje automatycznie, albo nie zrobi tego dokładnie tak jakbyśmy chcieli.
A wtedy się okazuje że różnica w prędkości jest, i to znaczna.

Wiem, jest coś takiego jak “compiler intrinsics” czyli niby-wysokopoziomowe podejście do takich opcjonalnych instrukcji (w skrócie: funkcje gwarantujące wygenerowanie inline konkretnej instrukcji maszynowej), i jest to jakieś rozwiązanie, ale niezbyt przypada mi do gustu, wygląda jak wymyślone na siłę żeby tylko uniknąć asma.

edytowany 2x, ostatnio: Azarien
elwis
  • Rejestracja:ponad 18 lat
  • Ostatnio:4 dni
3

Nieprawdą jest że w C możesz
Wygenerować dowolny kod asemblera. Choćby sposób zarządzania stosem jest silnie podporządkowane logice tego języka. Na przykład w x86 można łatwo wywołać procedurę ze zmodyfikowaną kontynuacją (adres powrotu na stos i używasz jmp zamiast call). Być może kiedyś potrzebowalbyś użyć instrukcji zarządzających cache w nietypowy sposób (btw jest jeden atak na SMM który je wykorzystuje), albo jeszcze czego? X86 ma bardzo rozbudowaną kolekcję wywołań. Na ile kompilator może się domyśleć, nie wiem, jednak wiem tyle że przy dzisiejszej mocy obliczeniowej takie rzeczy rzadko zdają się mieć sens, no chyba że na jakiś mikrokontroler.
Natomiast ograniczenie logiki może się kiedyś okazać, że tam jest jeszcze dużo ciekawych lekcji programowania do odrobienia.
Również prawdą jest że warto ogarniać assemblera po to żeby widzieć jak działa procesor i co jest niemożliwe albo trudne do wymyślenia w oderwaniu od specyfiki sprzętu. Poza tym w bezpieczeństwie i reverse engineeringu to ani rusz.
Raczej nie pisałbym ani czytał assemblera wprost, raczej bym automatyzował. Chociaż jak robiłem w firmware security to zdarzyło się napisać implementację ataku to bez dobrego ogaru assemblera to mogiła. :)


edytowany 3x, ostatnio: elwis
several
  • Rejestracja:prawie 16 lat
  • Ostatnio:2 minuty
1

Żaden kompilator ( nawet te na AVR'y ) nie zoptymalizuje kodu tak dobrze jak doświadczony programista znający assembler.

Dokładnie, bo kompilatory są pisane przez juniorów, którzy nie znają asemblera. Sory za złośliwość, ale jeśli programista piszący aplikację wpadł na jakąś optymalizację to niemal na pewno została ona już zaimplementowana w kompilatorze. Wyjątkiem są bardzo niszowe operacje, albo możliwość/konieczność użycia specyficznej instrukcji.


edytowany 1x, ostatnio: several
katakrowa
Przejrzyj kiedyś kod wynikowy ASM w debugerze a szybko zmienisz zdanie.
several
@katakrowa: ależ zerkałem w kod wynikowy, w każdym przypadku wystarczyło zastosować znane optymalizacje bez używania wstawek. Tyle, że ja nie programuje embedded.
PerlMonk
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa 🐪
  • Postów:1719
0
lion137 napisał(a):

ale nie warto drzeć szat o każdy cykl

Chyba, że Piszesz gry wideo.

Dyplomatycznie mogę odpowiedzieć tak: jest o co walczyć, ale nie jestem pewien kto (który producent) to robi. Jeśli piszesz .kkrieger to ok. Jakoś w grach AAA częściej widzę nacisk na rzeczy inne, niż wyciśnięcie każdego herca ze sprzętu.


Nie sztuka uciec gdy w dupie sztuciec. 🐪🐪🐪
MI
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:85
0
PerlMonk napisał(a):
lion137 napisał(a):

ale nie warto drzeć szat o każdy cykl

Chyba, że Piszesz gry wideo.

Dyplomatycznie mogę odpowiedzieć tak: jest o co walczyć, ale nie jestem pewien kto (który producent) to robi. Jeśli piszesz .kkrieger to ok. Jakoś w grach AAA częściej widzę nacisk na rzeczy inne, niż wyciśnięcie każdego herca ze sprzętu.

Czyli znając assemblera można wycisnąć więcej w jakiejś grze, tak? Np. osiągnąć więcej fpsów ? Bo już zgłupiałem jeśli chodzi o assemblera. Jedni piszą, że to relikt przeszłości, drudzy, że warto. Obecnie czytam ,,Asemblera programowanie'' wyd. Helion ale jedyne sensowne zastosowanie jakie przychodzi mi do głowy to pisanie cracków do gier. Zastanawiam się czy możliwe jest napisanie w assemblerze wirusa niezależnego od systemu operacyjnego.

Szalony Programista
Szalony Programista
Nie zostawię cię bez odpowiedzi, ale nie będzie cię chyba satysfakcjonować, tak możesz uzyskać więcej fpsów w grze, nadpisując funkcje, które np. generują jakiś dym, ogień, zbędny rendering, przez co odciąży się karta graficzna, a ty nie będziesz musiał oglądać np. smug dymu. A tak nie mam pomysł innego co można było by zrobić, prócz ograniczenia pewnych funkcji w danej grze.
katakrowa
Assembler nigdy nie będzie reliktem bo on jest wprost odwzorowaniem kodu maszynowego, który finalnie jest podstawą działania każdego programu komputerowego.
AK
  • Rejestracja:prawie 7 lat
  • Ostatnio:około miesiąc
  • Postów:3561
1
PerlMonk napisał(a):
katakrowa napisał(a):

Żaden kompilator ( nawet te na AVR'y ) nie zoptymalizuje kodu tak dobrze jak doświadczony programista znający assembler.

<ironia>Fajny truizm.</ironia>

W "dzisiejszych czasach" wstawki asemblerowe rzadko kiedy dają wymierne korzyści. Lata rozwoju informatyki dały nam algorytmy i języki wysokiego poziomu a kompilatory mają dobre (może nie idealne) możliwości optymalizacji pod sprzęt. Czy warto poświęcać kilka(naście) godzin na wstawkę w imię kilku procent? Znam przynajmniej kilku dyrektorów w większych firmach, którzy wyśmieją dupą każdego programistę, który walczy o megaherce.
Odpowiadam: warto znać konsekwencje swojej działalności, ale nie warto drzeć szat o każdy cykl - chociaż czasem kobiety to robią.

Zgadzam się.
W dodatku przypomnę, że dawne procesory miały małą ilość rejestrów, z których każdy miał jakiś indywidualny ficzer, specjalnie pod zdolnego programistę, a trudno było uzyskać dobry kompilat z np C.
Dziś procesory mają np 32 bliźniacze rejestry, ideał dla kompilatora, a mocna bariera do ręcznej optymalizacji


Bo C to najlepszy język, każdy uczeń ci to powie
katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
1
PerlMonk napisał(a):
katakrowa napisał(a):

Żaden kompilator ( nawet te na AVR'y ) nie zoptymalizuje kodu tak dobrze jak doświadczony programista znający assembler.

W "dzisiejszych czasach" wstawki asemblerowe rzadko kiedy dają wymierne korzyści. Lata rozwoju informatyki dały nam algorytmy i języki wysokiego poziomu a kompilatory mają dobre (może nie idealne) możliwości optymalizacji pod sprzęt. Czy warto poświęcać kilka(naście) godzin na wstawkę w imię kilku procent? Znam przynajmniej kilku dyrektorów w większych firmach, którzy wyśmieją dupą każdego programistę, który walczy o megaherce.
Odpowiadam: warto znać konsekwencje swojej działalności, ale nie warto drzeć szat o każdy cykl - chociaż czasem kobiety to robią.

Czy warto poświęcać kilka(naście) godzin na wstawkę w imię kilku procent?

Nie zawsze ale warto wiąże się to z np. aspiracjami bycia najlepszym. Spójrz na rywalizację szybkości algorytmów kompresujących, renderujących, samych CPU czy GPU. Różnice w czołówce są zawsze niewielkie dla użytkowników niezauważalne ale jednak zwycięzca może być tylko jeden. To właśnie te pojedyncze procenty dają zwycięstwo i to nie tylko w programowaniu ale we wszystkich dziedzinach (sport, produkcja, muzyka).

Warto też wspomnieć o rozwiązaniach serwerowych, urządzeniach sieciowych ( np. routery, switche ) gdzie optymalizacja odgrywa kluczową rolę zarówno ze względu na szybkość działania jak i wprost z tego wynikający pobór energii.

Wg mnie nie należy tego bagatelizować ale należy jednak zachować zdrowy rozsądek.


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
elwis
  • Rejestracja:ponad 18 lat
  • Ostatnio:4 dni
1

@Mirai: assembler nigdy nie będzie reliktem, bo i tak wszystko się do niego kompiluje. Natomiast pisanie w nim kodu jest reliktem. Nawet współczesny firmware to głównie C. Natomiast warto go znać z zupełnie innych przyczyn. Jedno drugiego nie wyklucza.


edytowany 1x, ostatnio: elwis
Azarien
bo i tak wszystko się do niego kompiluje – no niezupełnie, kompiluje się do kodu maszynowego. asembler to tak poziom wyżej.
elwis
Assembler jest tylko notacją dla kodu maszynowego. W kodzie assemblera pojawiają się informacje, które nie przekładają się na kod maszynowy (etykiety, tryb procesora, dodatkowe informacje dla debuggera), jednak assembler nie jest stratny wobec kodu maszynowego, mało istotny szczegół w tym wypadku.
Azarien
niektóre instrukcje można zakodować na różne sposoby, więc to nie jest takie 1:1.
elwis
Jakieś przykłady w którym wybór wydajniejszego jest nietrywialny?
Azarien
a dlaczego akurat wydajniejszego? i dlaczego nietrywialny? chodzi o sam fakt. przykładowo, krótki skok w x86 może zajmować 2 albo 3 bajty. zaczyna mieć to znaczenie gdy modyfikujemy istniejący kod binarny - to której użyto instrukcji wpływa na to co da się z tym zrobić, i ile mamy bajtów do dyspozycji. a na listingu asemblera nie widać różnicy. dlatego debugery przy każdej instrukcji podają jej bajty w formacie hex.
elwis
Dlatego, że te wartości ścisle określają wartość assemblera. Znacznie więcej zyskujesz na czytelnej formie assemblera niż tracisz na takim niuansie. Tym bardziej że takie rzeczy są zawarte w opisach instrukcji, więc włączam świadomość tego do znajomości assemblera. Jak potrzebujesz wymusić konkretny kod, możesz zapisać go jako dane. Spotkałem się już z takimi hackami.
elwis
One też są istotne w uzasadnieniu czemu dopuściłem się takiej nieścisłości, że wszystko kompiluje się do assemblera. Różnica jest nieistotna jeśli nie modyfikujemy istniejących binarek, czyli zupełnie nie ten przypadek.
enedil
Pojawia się więcej różnic, przykładowo, na x86 wystarczy skoczyć do adresu, który leżał w środku jakiejś instrukcji, i nagle dostajemy zupełnie inny kod maszynowy. Bardzo często duży jego fragment nie ma sensu, ale można krótkie fragmenty użyć w technice znanej jako return oriented programming.
elwis
Tak, rzeczywiście assembler nie pozwala konstruować takiego kodu. Jednak wciąż są to rzeczy których języki wysokiego poziomu tym bardziej nie umieją. U odniesieniu do sztuczek obfuskacyjnych, ataków i modyfikacji binarek, operacje na modzie maszynowym mogą być przydatne, jak już wspomniałem wyżej.
Delor
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 2 lata
3
katakrowa napisał(a):

Żaden kompilator ( nawet te na AVR'y ) nie zoptymalizuje kodu tak dobrze jak doświadczony programista znający assembler.

Tu jest przykład (linkowany kilkukrotnie na forum) dobrego programisty i jego próby optymalizacji. Fakt, bez wstawek asm.

edytowany 1x, ostatnio: Delor
MarekR22
ha wyprzedziłeś mnie z Mattem o 2 minuty :)
Delor
:) Brakowało mi go w tym wątku.
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:8 minut
8

Polecam nauczyć się asemblera tylko na tyle, żeby umieć go czytać.
Czasami warto zajrzeć "pod maskę" co kompilator wygenerował (zoptymalizowal), albo podczas deugowania.
Do tego służy zarąbista strona: https://godbolt.org/

Pisanie wstawek assemblerowaych nie ma sensu bo:

  • kod robi się nieprzenośny (a jak robisz wywołania systemowe to staje się przyczepiony do jednego sytemu).
  • utrzymanie takiego kodu jest kosztowne i bardziej wrażliwe na błędy
  • współczesne kompilatory C i C++ z właściwymi ustawieniami potrafią cuda, o których większość programistów asemblera nawet nie pomyśli.
  • myśląc o wydajności kodu najlepiej myśleć w kategorii złożoności zapisanego algorytmu.

Polecam obejrzeć


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
katakrowa
W jednym poście wymieszałeś wszystkie pojęcia tj.: złożoność algorytmu, optymalizacje kodu, który nic nie wnosi i samej optymalizacji. Są różne rodzaje optymalizacji i nie trzeba zaprzeczać sensowności optymalizacji realizowanych przez kompilatory wskazanych w powyższym filmie. Wciąż jednak twierdzę, że są miejsca w kodzie, których żaden kompilator nie zoptymalizuje tak dobrze jak człowiek i gdy walczymy o kilka procent dodatkowej wydajności to mają one sens.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.