Mein angeblich deterministisches Programm erzeugt eine von ein paar leicht unterschiedlichen Ausgaben in verschiedenen Läufen. Die Eingabe, der Compiler und der Computer sind unverändert. Ich bin mir nicht sicher, welche Ausgabe richtig ist, weil sie immer vernünftig aussieht.
Wie könnte das möglich sein? Neben einem irren Aufruf von rand ()?
Es könnte sein:
Auf verschiedene Arten:
Wir können sicherlich mehr Vermutungen anstellen, aber wenn Sie sinnvolle Hilfe erhalten möchten, wäre es vielleicht gut für Sie, die relevanten Teile Ihres Codes zu veröffentlichen: -)
Wenn Ihre Ausgabe von einer Adresse abhängt, die auf dem Heap zugewiesen ist:
%Vor%Bei jedem Lauf kann malloc () eine andere virtuelle Adresse zurückgeben - ganz zu schweigen von NULL, falls die Zuweisung fehlgeschlagen ist.
Neben einem stray Aufruf an rand ()
%code% ist vollständig deterministisch, solange Sie ihm den gleichen Anfangswert geben.
Die Verwendung des Werts eines Zeigers anstelle dessen, worauf er zeigt, führt immer zu interessanten Ergebnissen.
Ohne etwas Code zu sehen (TIPP HINZUFÜGEN), würde ich am besten nach einem Muster suchen. Vielleicht etwas Datum-Zeit-spezifische.
Versuchen Sie auch, nach Rennbedingungen zu suchen. Das kann nicht-deterministisch aussehen.
Wenn Ihr Programm float / double verwendet, kann es zu Abweichungen im Ergebnis kommen, wenn in einer Architektur Kontextwechsel erfolgt.
Auf x86 verwendet die FPU eine erweiterte Genauigkeit für das Zwischenergebnis, aber wenn sie im Arbeitsspeicher gespeichert wird (was passiert, wenn ein Kontext entweder einen Prozess oder einen Thread wechselt), geht diese Genauigkeit verloren. Das könnte zu einer kleinen Abweichung des Ergebnisses führen (wir haben ein solches Problem in unserem Programm entdeckt). Eine Möglichkeit, dieses Problem zu vermeiden, besteht darin, den Compiler aufzufordern, nicht FPU, sondern SSE für Fließkommaoperationen zu verwenden.
In den Programmen, die nicht viel mit der "Außenwelt" interagieren, ist die populäre Quelle des Nicht-Determinismus die Abhängigkeit vom Zeigervergleich. Von Zeit zu Zeit sieht man es vielleicht im Code: Wenn eine lexikographische Vergleichsfunktion keine Vergleichswerte mehr hat (alles ist gleich), vergleicht sie die Adressen von Objekten als letzte Möglichkeit. Dies kann zu unterschiedlichen Ordnungen führen, wenn die Objekte im dynamischen Speicher zugeordnet werden, da die tatsächlichen Zuweisungsorte von Plattform zu Plattform und von Lauf zu Lauf unterschiedlich sein können.
Offensichtlich eine neue Instanz des Mondphasen-Bugs .
Sie haben nicht viele Informationen gegeben. Jedoch, als jemand, der Echtzeit-Programmierung für einen Lebensunterhalt macht, die wahrscheinlichsten Schuldigen, die ich suche, wenn solche Dinge passieren, ist:
Zum Beispiel gab es einen solchen Fehler, bei dem ich einmal davon ausgegangen war, dass die gemeinsam genutzte Bibliothek nicht so "geteilt" war, wie ich dachte, und einen Griff aus einem Prozess zu verwenden, um eine Tabelle zu initialisieren, die in einem zweiten Prozess noch nicht initialisiert war. Abhängig davon, wie die Dinge gestartet wurden, die wichtige Daten in einem dritten Prozess verursacht haben oder nicht, werden sie zerstört.
Irgendein undefiniertes Verhalten. h. es werden Hunderte von Seiten benötigt, um jede mögliche Quelle der Veränderung der Ausgabe zu erklären. Versuchen Sie das Debuggen, um zu finden, wo eine Änderung auftritt, oder lesen Sie eine C ++ - Spezifikation.