Befehl für Compiler nicht verschiebbar machen
-
Hallo,
leider wusste ich keinen guten Titel für die Frage...
Ich habe folgendes Problem. Man stelle sich vor man habe folgenden Code:int myMethod() { xyz(1); //beliebig viel Code xyz(2) return 0; }
Was die Methode xyz macht ist im Grund irrelevant. Wichtig ist dass der erste und letzte Befehl einer Methode diese xyz-Methode aufrufen muss (Ausnahme das return). Wenn ich das nun aber compiliere und mir das Disassembly anschaue, dann optimiert der Compiler da rum und die CALLs der Methode xyz verschieben sich kreuz und quer innerhalb der Methode.
Gibt es eine Möglichkeit einen Aufruf so zu kennzeichnen das dem Compiler nicht erlaubt wird ihn zu verschieben ?
-
Wenn das wirklich wichtig wäre, würde der Compiler es auch nicht verschieben.
-
Also es gibt schon Gründe, warum man nicht möchte, dass der Compiler die Reihenfolge von Funktionsaufrufen nicht verschieben soll. Ich denke da Logging Funktionen, die bei Eintritt und Verlassen einer Funktion ausgeführt werden sollen, um spätere Fehleranalyse zu vereinfachen. Wenn der Compiler jetzt die Aufrufe verschiebt sind ist das Loggen für die Katz.
Eine Lösung dazu habe ich leider nicht.
-
Dass ist das Problem, Methode xyz erzeugt derzeit nur anhand des Übergabewerts eine eindeutige Zahl die weggespeichert wird, mit dem restlichen Programm aber nichts mehr zu tun hat. Es ist also für den Compiler vollkommen egal wo es in der Methode gemacht wird, daher schiebt ers wohl auch rum.
Daher ja auch die Frage, ob es eine Möglichkeit gibt Befehle zu pinnen oder so zu kennzeichnen das sie nicht verschoben werden, sie quasi "wichtig" machen (auch wenn sies nicht sind...).
-
DocShoe schrieb:
Also es gibt schon Gründe, warum man nicht möchte, dass der Compiler die Reihenfolge von Funktionsaufrufen nicht verschieben soll. Ich denke da Logging Funktionen, die bei Eintritt und Verlassen einer Funktion ausgeführt werden sollen, um spätere Fehleranalyse zu vereinfachen. Wenn der Compiler jetzt die Aufrufe verschiebt sind ist das Loggen für die Katz.
Aber Loggingaufrufe werden nicht verschoben, weil sie tatsächlich was machen. Der Compiler darf nur insofern rumschieben, dass die Ausgabe des Programm am Ende exakt die gleiche ist wie ohne verschieben.
hasso84 schrieb:
Dass ist das Problem, Methode xyz erzeugt derzeit nur anhand des Übergabewerts eine eindeutige Zahl die weggespeichert wird, mit dem restlichen Programm aber nichts mehr zu tun hat. Es ist also für den Compiler vollkommen egal wo es in der Methode gemacht wird, daher schiebt ers wohl auch rum.
Ich stelle mich auf die Seite des Compilers: Wieso ist es dann wichtig, wann die Methode aufgerufen wird, wenn mit dem Wert nichts gemacht wird?
Entsprechend kannst du das verhindern, indem du mit dem Wert etwas machst.
-
SeppJ schrieb:
Ich stelle mich auf die Seite des Compilers: Wieso ist es dann wichtig, wann die Methode aufgerufen wird, wenn mit dem Wert nichts gemacht wird?
Entsprechend kannst du das verhindern, indem du mit dem Wert etwas machst.
Natürlich, der Compiler macht ja nichts falsch oder hat Unrecht, behaupte ich auch nicht. Es ging eben nur darum das der Aufruf in diesem speziellen Fall genau da bleibt wo er ist, auch wenn man ihn verschieben könnte.
Klar, ich kann mit dem Wert jetzt künstlich was machen, dann verschiebt ers nicht mehr (schon probiert) aber das ist einfach unnötiger Code den ich eigtl überhaupt nicht brauche (und dadurch dass das Programm viele 1000ende solcher Aufrufe hat summiert sich der unnötige Code schnell auf) daher ja die Frage ob man das auch einfach umgehen/abschalten kann.
-
Es ging eben nur darum das der Aufruf in diesem speziellen Fall genau da bleibt wo er ist, auch wenn man ihn verschieben könnte.
Da bleibt natuerlich die Frage nach dem warum. Warum soll er dort bleiben?
-
Das würde den Rahmen sprengen, grob:
Man stelle sich Synchronisationspunkte vor die im compilierten Code an fest vorgegebenen Stellen sitzen müssen (in meinem Fall am Anfang und Ende jeder Methode). So etwas nachträglich einzufügen gestaltet sich eben nur schwer, weil ichs im Quellcode lange am Anfang und Ende jeder Funktion einfügen kann, wenns der Compiler dann wegschiebt.
Für den Compiler ist es ja egal wo der Aufruf liegt, für die CPU die das Ganze aber später mal nutzt ist es das absolut nicht.
-
Wenn ich dich richtig verstehe, dann willst du einfach nur verhindern, dass gleichzeitig jemand anderes die Methode ausführen kann?
Dann schau dir mal Semaphore/Mutexe an. Sonst würde mir auch kein Grund einfallen, warum man so etwas machen wollte?
-
Nein, nochmal anders.
Ich habe eine C++ Programm, das wird compiliert und der erzeugte Maschinencode wird dann genommen und in eine ganz andere CPU gesteckt (keine die man einfach beim ARLT kauft...).
Und diese "andere CPU" ist darauf angewiesen das diese Aufrufe, INNERHALB des Maschinencodes an festen, vorgegebenen Positionen sitzen.
Nun gibt es 2 Möglichkeiten:
1. ich nehme den Maschinencode und füge es dort nachträglich ein
2. ich nehme den C++ - Quellcode und füge es dort ein (was schneller geht)Dadurch das der Compiler beim compilieren von Quell- zu Maschinencode diese Aufrufe aber verschiebt, passt es am Ende im Maschinencode nicht mehr. Und das würde ich gerne verhindern. Daher suche ich eine Möglichkeit den Compiler daran zu hindern beim compilieren zu verschieben, auch wenn es für ihn keinen Unterschied macht.
Aber diese Möglichkeit scheint es wohl nicht zu geben.
-
hasso84 schrieb:
Für den Compiler ist es ja egal wo der Aufruf liegt, für die CPU die das Ganze aber später mal nutzt ist es das absolut nicht.
Sobald der Code aber wichtig würde (dafür bräuchte es keine Ausgabe, sondern ein Zugriff auf eine globale und oder volatile Variable (die dann auch benutzt wird!) sollte reichen) würde der Compiler den Code nicht mehr verschieben. Ich glaube du machst dir gerade viel zu viele Gedanken. Und zwar an einem Testfall, der deine Anwendung nicht wiederspiegelt.
Der resultierende Code am Ende wird jedenfalls effektiv genauso funktionieren, als ob alles in der richtigen Reihenfolge ist.
-
Darf man fragen, was du genau vor hast? So kann man dir besser konkrete Vorschläge unterbreiten. Willst du eine Interrupt-Routine schreiben? Alles nur reine Spekulation! Rein theoretisch müsste es für dich aber auch reichen, einfach die Optimierung auszuschalten.
-
Es sollte doch _eigentlich_ reichen, dass xyz eine externe Funktion ist. Der Compiler hat kein Wissen über ihr Verhalten und muss daher konservative Annahmen machen.
-
Fall 1:
sub_4131D0 proc near call sub_4131DA ;anderer Code sub_4131D0 endp
Fall 2:
sub_4131D0 proc near ;anderer Code call sub_4131DA ;anderer Code sub_4131D0 endp
Fall 3:
sub_4131D0 proc near ;anderer Code call sub_4131DA sub_4131D0 endp
Dadurch das der CALL den restlichen Code nicht beeinflusst, sind alle 3 Fälle lauffähig und tun dasselbe.
Die CPU auf der das später aber mal laufen soll, aktzeptiert ausschließlich Fall 1. Auch wenn Fall 2 und Fall 3 das Gleiche tun. Mir ist durchaus bewusst das alles eigtl dasselbe ist, ich kann nur leider nicht ändern dass es der Ziel CPU nicht egal ist wie es aufgebaut ist. Daher die verzweifelten Versuche den Compiler zu zwingen es da stehen zu lassen wo ichs hinschreibe.
-
hasso84 schrieb:
Die CPU auf der das später aber mal laufen soll, aktzeptiert ausschließlich Fall 1. Auch wenn Fall 2 und Fall 3 das Gleiche tun. Mir ist durchaus bewusst das alles eigtl dasselbe ist, ich kann nur leider nicht ändern dass es der Ziel CPU nicht egal ist wie es aufgebaut ist. Daher die verzweifelten Versuche den Compiler zu zwingen es da stehen zu lassen wo ichs hinschreibe.
Wenn dein Compiler keinen lauffähigen Code für die Plattform erzeugt, dann ist das ein Fehler im Compiler.
-
SeppJ schrieb:
Wenn dein Compiler keinen lauffähigen Code für die Plattform erzeugt, dann ist das ein Fehler im Compiler.
Oder ein "Missbrauch" des Compilers. Der OP benutzt offenbar den Compiler für eine Plattform, für die er nicht gedacht ist. (Und für die es evtl. keinen geeigneten Compiler gibt). Er sucht jetzt nach Mitteln, das Verhalten des Compilers auf seine Zielplattform zurechtzustutzen.
Was er erreichen will, wissen wir jetzt. Aber nicht, mit welchem Compiler.
Da es hier ganz offensichtlich nicht um portablen Code geht, können hier gerne auch Compilerspezifika gefragt sein - daher verschieb ichs mal ins entsprechende Forum, in der Hoffnung, dass die Info noch kommt...
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ (auch C++0x) in das Forum Compiler- und IDE-Forum verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Gut dann konkret gefragt, welche CPU und welcher Compiler? Die Sprachdefinition von C++ gibt das nicht her, was du haben moechtest. D.h. du suchst dir einen Compiler mit spezifischen Erweiterungen oder nutzt eine andere Sprache. Oder ... naja es gibt sicher noch andere Optionen.