Wie kann man verhindern, dass gcc einige Anweisungen in C optimiert?

Lesezeit: 3 Minuten

Benutzeravatar von ZelluX
ZelluX

Um eine Seite unsauber zu machen (das Dirty-Bit im Seitentabelleneintrag einzuschalten), berühre ich die ersten Bytes der Seite wie folgt:

pageptr[0] = pageptr[0];

Aber in der Praxis wird gcc die Aussage durch Dead-Store-Eliminierung ignorieren. Um zu verhindern, dass gcc es optimiert, schreibe ich die Anweisung wie folgt um:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

Es scheint, dass der Trick funktioniert, aber etwas hässlich. Ich würde gerne wissen, ob es Anweisungen oder Syntax gibt, die den gleichen Effekt haben? Und ich möchte keine verwenden -O0 Flagge, da dies auch eine große Leistungseinbuße mit sich bringt.

  • @Mark -O0 stoppt die Optimierung, verlangsamt aber auch die Programmleistung. Ich möchte nur die Optimierung dieses Codeschnipsels verhindern 😛

    – ZelluX

    8. Februar 2010 um 5:53 Uhr

  • Ich möchte das in der Vergangenheit sogar mit hinzufügen -O0 hat tote Code-“Optimierung” nicht verhindert, zB wenn GCC feststellt, dass ein Code keine Wirkung hat, entfernt es ihn einfach. AFAIK ist dies eine Stufe noch vor -O0… Aber das ist nur meine Erfahrung

    – Glattware

    5. März 2020 um 9:01 Uhr

Sie können verwenden

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

um Optimierungen seit GCC 4.4 zu deaktivieren.

Weitere Informationen finden Sie in der GCC-Dokumentation.

  • Es ist jedoch erwähnenswert, dass dies nur für ganze Funktionen funktioniert, nicht für bestimmte Anweisungen: gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/… “Jede Funktion, die nach diesem Punkt definiert wird, ist so, als ob das Attribut ((optimize(“STRING”))) für diese Funktion angegeben wurde.”.

    – Ciro Santilli OurBigBook.com

    26. Juni 2019 um 15:21 Uhr

Benutzeravatar von FRob
FRob

Anstatt die neuen Pragmas zu verwenden, können Sie auch verwenden __attribute__((optimize("O0"))) für Ihre Bedürfnisse. Dies hat den Vorteil, dass es nur auf eine einzelne Funktion angewendet wird und nicht alle Funktionen, die in derselben Datei definiert sind.

Anwendungsbeispiel:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}

  • Was ist, wenn ich kein a verwende?-OlevelOption, aber ich habe die einzelnen Optionen verwendet, die es separat aktiviert? (In meinem Fall kann ich nicht feststellen, welche einzelne Optimierungsoption den Code bricht.).

    – Benutzer2284570

    16. April 2015 um 11:26 Uhr

  • Keine der Empfehlungen rund um flüchtige Arbeit mehr. GCC-Compiler-Header können volatile + O0 nicht verarbeiten. Während Schleifen optimiert werden, da -faggressive-loop-optimization standardmäßig ist, blockiert nur O0 dies. Aus diesen Gründen ist O0 und kein Volatil in der nicht optimierten Funktion jetzt die richtige Antwort.

    – rickfoosusa

    16. September 2020 um 21:03 Uhr

Benutzeravatar von Dietrich Epp
Dietrich Ep

Das Deaktivieren der Optimierung behebt das Problem, ist jedoch unnötig. Eine sicherere Alternative besteht darin, es dem Compiler illegal zu machen, den Speicher mithilfe von zu optimieren volatile Typqualifizierer.

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

Das volatile Der Typqualifizierer weist den Compiler an, beim Speichern und Laden im Speicher streng zu sein. Ein Zweck von volatile soll den Compiler wissen lassen, dass der Speicherzugriff Seiteneffekte hat und daher beibehalten werden muss. In diesem Fall verursacht der Speicher als Nebeneffekt einen Seitenfehler, und Sie möchten, dass der Compiler den Seitenfehler beibehält.

Auf diese Weise kann der umgebende Code noch optimiert werden, und Ihr Code ist auf andere Compiler portierbar, die GCCs nicht verstehen #pragma oder __attribute__ Syntax.

  • Ich würde sagen, dass dies dem Ausschalten von Optimierungen vorzuziehen ist. Sie können mit dieser Methode noch von anderen Optimierungen profitieren.

    – Ben S

    8. Februar 2010 um 5:54 Uhr

  • Die Lösung von Dietrich Epp funktioniert nicht unter ARM4.1-Compiler. Auch die Lösung von ZelluX funktioniert nicht. Eine alternative Methode, um dies für ARM4.1 zum Laufen zu bringen, ist in der Lösung von ZelluX, make ‘Temp‘ a globale flüchtige Variable.

    – Preetham Nanjappa

    30. November 2011 um 11:15 Uhr

  • Das ist ziemlich schlecht für besagten Compiler.

    – Alexey Frunze

    30. November 2011 um 11:25 Uhr

  • @Shocker: GCC kann die Variable immer noch optimieren, ohne den tatsächlichen Speicherzugriff zu optimieren. Das sind verschiedene Themen.

    – Dietrich Ep

    14. August 2017 um 17:39 Uhr

  • @jww: Diese Verwendung passt zu dem, was in diesem Blogbeitrag beschrieben wird. volatile bedeutet, dass der Speicherzugriff wie geschrieben erfolgen muss, was genau das ist, was wir wollen. Mit anderen Worten, wir haben sorgfältig darüber nachgedacht, und es bedeutet, was wir denken, dass es bedeutet.

    – Dietrich Ep

    13. Januar 2018 um 19:37 Uhr

1423720cookie-checkWie kann man verhindern, dass gcc einige Anweisungen in C optimiert?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy