Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Assembler ::  ARM GCC Optimierung     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
fenrayn
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2016
Beiträge: 43
Beitrag fenrayn Mitglied 07:10:27 26.05.2016   Titel:   ARM GCC Optimierung            Zitieren

Hallo, ich versuche mich etwas in den Cortex M0 einzuarbeiten. Dabei bin ich auf folgendes Problem gestoßen:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void __attribute__((optimize("O0"))) blub(int* t1, int* t2) {
    __asm(
            "ldr r5, [%[t2]]\n"
            "ldr r4, [%[t1]]\n"
            "add r5, r4, r5\n"
            "str r5, [%[t1]]\n"
            :: [t1]"r"(t1), [t2]"r"(t2)
            );
}
 
int main() {
    dev_io::init();
 
    int a = 1;
    int b = 2;
    blub(&a, &b);
    if(a == 3) {
        dev_io::set_ledR();
    }
    dev_io::set_ledG();
    for(;;) {
    }
    return 0;
}


Ich programmiere in C++ mit inline Assembler. Bei eingeschalteter Codeoptimierung optimiert mir der Compiler den blub-Funktionsaufruf, die Konstantenzuweisung auf a und b, sowie die if-Bedingung UND das setzen von ledR einfach raus ...
Ich muss entweder die Codeoptimierung komplett abschalten oder die Funktion Blub das oben stehende Attribut spendieren, sonst leuchtet meine rote LED nicht ...

Weiß jemand was da schief läuft?


Zuletzt bearbeitet von fenrayn am 07:10:49 26.05.2016, insgesamt 1-mal bearbeitet
Techel
Mitglied

Benutzerprofil
Anmeldungsdatum: 19.09.2015
Beiträge: 746
Beitrag Techel Mitglied 07:21:34 26.05.2016   Titel:              Zitieren

Versuch es mal mit asm volatile statt nur asm. Ansonsten auf inline Assembler verzichten.


Zuletzt bearbeitet von Techel am 07:22:16 26.05.2016, insgesamt 1-mal bearbeitet
fenrayn
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2016
Beiträge: 43
Beitrag fenrayn Mitglied 07:37:33 26.05.2016   Titel:              Zitieren

Volatile bringt leider auch nichts.

Zitat:
Ansonsten auf inline Assembler verzichten.


Nur sehr ungern!
rkhb
Mitglied

Benutzerprofil
Anmeldungsdatum: 19.09.2010
Beiträge: 331
Beitrag rkhb Mitglied 08:43:21 26.05.2016   Titel:              Zitieren

GCC-Inline-Assembly ist ein Horror für sich. Ich vermute hier mal ins Blaue hinein:

Nach dem ersten Doppelpunkt kommen die Output-Operanden, nach dem zweiten Doppelpunkt die Input-Operanden, nach dem dritten Doppelpunkt die Clobber-Liste. Soweit ich sehe, gibt es keine Output-Operanden und keine Clobber-Liste. GCC denkt sich also, dass dieser Code-Teil gar nichts verändert und kürzt ihn weg. Es könnte sein, dass schon der Eintrag von R4 und R5 in die Clobber-Liste das Problem löst.

Ein bisschen erstaunt bin ich, dass die Angabe der Register ohne Prozentzeichen bzw. zweifaches Prozentzeichen klappt.

Der if-Block wird weggekürzt, da GCC nicht erkennen kann, dass Du die Variable (!) 'a' trickreich per Registerzugriff in der Funktion 'blub' setzen willst. GCC denkt, der Wert von 'a' ist immer noch 1 und die if-Bedingung niemals erfüllt. Probier mal der Definition von a ein volatile voranzustellen: 'volatile int a = 1;'.

viele grüße
ralph


Zuletzt bearbeitet von rkhb am 17:39:53 26.05.2016, insgesamt 2-mal bearbeitet
fenrayn
Mitglied

Benutzerprofil
Anmeldungsdatum: 20.05.2016
Beiträge: 43
Beitrag fenrayn Mitglied 16:59:15 26.05.2016   Titel:              Zitieren

Wenn ich die Variablen volatile definiere klappt alles wunderbar. Ich hatte aber gehofft das Funktionen die inline-Assembler enthalten ganz normal benutzt werden können :/
lerwin
Unregistrierter




Beitrag lerwin Unregistrierter 17:40:29 26.05.2016   Titel:              Zitieren

Wie schon gesagt wurde, der Compiler weiß nicht das *t1 vom Assembler Code geändert wird (ist Ausgabewert), als auch das r4 und r5 modifiziert werden (das kann zu falschem Code führen, da GCC glaubt der Inhalt dieser Register sei nicht Flüchtig).
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
nachtfeuer
Moderator

Benutzerprofil
Anmeldungsdatum: 08.04.2010
Beiträge: 2029
Beitrag nachtfeuer Moderator 20:54:07 27.05.2016   Titel:              Zitieren

Assembler behindert die Codeoptimierung, die für die Hochsprache gedacht ist.

Deswegen wäre die bessere Reihenfolge eher so:
erst Hochsprache
dann "optimieren"
dann wenn (überhaupt noch nötig) von Hand nachbessern.

Oder eben Codeabschnitte wie oben gleich komplett in Assembler schreiben (und auf "optimize" verzichten).
camper
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.08.2004
Beiträge: 6874
Beitrag camper Mitglied 22:59:47 27.05.2016   Titel:              Zitieren

Die Constraints sind in jedem Falle falsch.
Weil der Code keinen explizit deklarierten Output hat, benötigen wir ausserdem volatile.
C:
1
2
3
4
5
6
7
8
9
10
void blub(int* t1, int* t2) {
    __asm volatile (
            "ldr r5, [%[t2]]\n"
            "ldr r4, [%[t1]]\n"
            "add r5, r4, r5\n"
            "str r5, [%[t1]]\n"
            :: [t1]"r"(t1), [t2]"r"(t2)
            : "r4", "r5", "memory", "cc"
            );
}


Besser ist die Verwendung von Speicheroperanden, dann kann auch der Output vernünftig deklariert werden:
C:
1
2
3
4
5
6
7
8
9
10
11
void blub(int* t1, int* t2) {
    __asm(
            "ldr r5, %[t2]\n"
            "ldr r4, %[t1]\n"
            "add r5, r4, r5\n"
            "str r5, %[t1]\n"
            : [t1]"=m"(*t1)
            : "0"(*t1), [t2]"m"(*t2)
            : "r4", "r5", "cc"
            );
}


Zuletzt bearbeitet von camper am 23:00:13 27.05.2016, insgesamt 1-mal bearbeitet
turi
Unregistrierter




Beitrag turi Unregistrierter 00:55:44 28.05.2016   Titel:              Zitieren

Gezeigter Code ändert keine Flags, daher ist das "cc" unnötig.
C++ Forum :: Assembler ::  ARM GCC Optimierung   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.