Wstawki asemblerowe w C++

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 ?

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 :>

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....

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...

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ą".

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.

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.

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ą.

0

ale nie warto drzeć szat o każdy cykl

Chyba, że Piszesz gry wideo.

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.

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. :)

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.

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.

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.

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

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.

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.

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.

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ć

1 użytkowników online, w tym zalogowanych: 0, gości: 1