Erstellt die Verwendung von Heap-Speicher (malloc / new) ein nicht deterministisches Programm?

76

Ich habe vor einigen Monaten begonnen, Software für Echtzeitsysteme in C für Weltraumanwendungen und auch für Mikrocontroller mit C ++ zu entwickeln. In solchen Systemen gibt es eine Faustregel, dass man niemals Heap-Objekte erstellen sollte (also kein Malloc / New), da dies das Programm nicht deterministisch macht . Ich konnte die Richtigkeit dieser Aussage nicht überprüfen, als mir die Leute das sagten. Also, Ist das eine richtige Aussage?

Die Verwirrung für mich ist, dass Determinismus meines Wissens bedeutet, dass das zweimalige Ausführen eines Programms zu genau demselben Ausführungspfad führt. Nach meinem Verständnis ist dies ein Problem bei Multithread-Systemen, da bei mehrmaliger Ausführung desselben Programms jedes Mal unterschiedliche Threads in unterschiedlicher Reihenfolge ausgeführt werden können.

Der Quantenphysiker
quelle
12
Die dynamische Speicherzuweisung und -entzuweisung leidet unter dem Problem der Speicherfragmentierung, das in Echtzeitanwendungen nicht erwartet wird.
Gaurav Pathak
22
Grundsätzlich geht es so: PC-Programmierer lernen den Umgang mit malloc / new. Sie kommen zu eingebetteten Systemen, bei denen der Heap überhaupt keinen Sinn ergibt, da diese mit einer völlig anderen Architektur und Denkweise erstellt wurden. PC-Programmierer ist verärgert, das haben sie mir in der Schule nicht gedacht! Und ich benutze den Haufen schon seit Ewigkeiten auf dem PC! Der PC-Programmierer ignoriert alle und führt weiterhin die Heap-Zuweisung durch. Das Programm stellt sich als Mist heraus, voller Fehler und schlechter Leistung. PC-Programmierer wird gefeuert. Der Programmierer für eingebettete Systeme übernimmt das Chaos. Das Programm wird von Grund auf neu geschrieben.
Lundin
11
@ PeterA.Schneider Als Physiker, der in Teilchen- und Atomphysik promoviert hat, fällt es mir bereits sehr schwer, die Grenze zwischen dem Deterministischen und dem Nichtdeterministischen in Computern zu ziehen. Das liegt daran, dass wir wohl in einem nicht deterministischen Universum leben. Ich verstehe, dass meine Frage leicht ein zirkuläres Argument auslösen kann, ob etwas jemals deterministisch ist, bevor es unter bestimmten Annahmen als deterministisch bezeichnet wird. Der Sprachgebrauch des Determinismus beschränkt sich hier jedoch darauf, wie Informatiker ihn verwenden, was praktisch nicht mit der realen Zufälligkeit in der Natur zusammenhängt.
Der Quantenphysiker
8
@ PeterA.Schneider Es ist trivial, in fast allen modernen Computern nicht deterministische Dinge zu tun. Eine einfache Möglichkeit: Beachten Sie das niedrigstwertige Bit des Befehlszählers des Prozessors in einer Routine, die darauf wartet, dass ein Lesevorgang abgeschlossen ist. Dies wird durch Scherturbulenzen in der Drehzahl der Scheibe beeinflusst. Ähnliches können Sie mit einem Netzwerkpaket tun, das durch mikroskopische Zonentemperaturschwankungen in Quarzkristallen beeinflusst wird, die den Versatz zwischen der Netzwerkschnittstellentakt und der CPU-Uhr beeinflussen. Sie können thermisches Rauschen aus Audioeingängen extrahieren. Es gibt viele andere Möglichkeiten.
David Schwartz
5
@ PeterA.Schneider: Die meisten x86-CPUs dieser Tage (Intel seit IvyBridge) verfügen über eine integrierte rdrandAnweisung, die Sie über einen normalen User-Space-Prozess ausführen können. Es gibt echte Hardware-Zufälligkeit von einem mit AES konditionierten thermischen Rauschgenerator (es sei denn, die NSA hat das Design geschwächt ...). Natürlich rdtscist es auch nicht deterministisch, wie David betont, insbesondere wenn man nur einen einzigen Prozess betrachtet, aber ein guter Punkt, dass die Synchronisation zwischen verschiedenen Taktdomänen einen echten Nichtdeterminismus ergibt.
Peter Cordes

Antworten:

71

Im Kontext von Echtzeitsystemen ist Determinismus mehr als ein wiederholbarer "Ausführungspfad". Eine weitere erforderliche Eigenschaft ist, dass das Timing von Schlüsselereignissen begrenzt ist. In harten Echtzeitsystemen stellt ein Ereignis, das außerhalb des zulässigen Zeitintervalls auftritt (entweder vor dem Beginn dieses Intervalls oder nach dem Ende), einen Systemfehler dar.

In diesem Zusammenhang kann die Verwendung der dynamischen Speicherzuweisung zu Nichtdeterminismus führen, insbesondere wenn das Programm ein unterschiedliches Muster für die Zuweisung, Freigabe und Neuzuweisung aufweist. Der Zeitpunkt für die Zuweisung, Freigabe und Neuzuweisung kann im Laufe der Zeit variieren - und daher ist der Zeitpunkt für das gesamte System unvorhersehbar.

Peter
quelle
28
Unvorhersehbare Timings machen ein System jedoch nicht in Echtzeit. Wenn eine Zuordnung rand()Millisekunden dauert und die Zeitgrenze größer als ist RAND_MAX, ist das System in Echtzeit.
MSalters
4
@ MSalters - das stimmt. Ein Echtzeitsystem erfordert, dass die Zeitvorhersagen vorhersehbar begrenzt sind, und nicht, dass jeder Zeitpunkt im Voraus vorhersehbar ist.
Peter
1
Bitte: Warum nennst du es dann "(Nicht-) Determinismus"? Es ist nur eine Operation ohne genau definierte Worst-Case-Ausführungszeit. Es wird nur dann "nicht deterministisch", wenn die Zuordnung z. B. von anderen Prozessen / Teilen der Anwendung beeinflusst wird, die mit dem "Äußeren" interagieren (z. B. Warten auf einen Menschen, der eine Taste drückt).
Daniel Jour
Wenn es sich um ein wirklich geschlossenes System handelt, könnte man es als deterministisch bezeichnen, aber es wäre immer noch chaotisch , dh unmöglich vorherzusagen. Davon abgesehen bezweifle ich, dass es sich um ein wirklich geschlossenes System handelt, da dies ziemlich nutzlos wäre.
John Wu
@DanielJour - Die Definition eines Echtzeitsystems beinhaltet das deterministische Timing von Ereignissen (z. B. kann durch Analysieren der Eigenschaften des Systems bestimmt werden, dass Ereignis B zwischen x und y Millisekunden nach Ereignis A auftritt). Wenn für das Auslösen oder Reagieren auf Ereignisse keine definierte Worst-Case-Ausführungszeit festgelegt ist, kann das System seine Echtzeitanforderungen nicht erfüllen. In einem weichen Echtzeitsystem kann dies bis zu einem gewissen Grad akzeptabel sein. In einem harten Echtzeitsystem ist dies nicht der Fall.
Peter
40

Der Kommentar ist wie angegeben falsch.

Durch die Verwendung eines Heap-Managers mit nicht deterministischem Verhalten wird ein Programm mit nicht deterministischem Verhalten erstellt. Das ist aber offensichtlich.

Etwas weniger offensichtlich ist die Existenz von Heap-Managern mit deterministischem Verhalten. Das vielleicht bekannteste Beispiel ist der Pool-Allokator. Es hat ein Array von N * M Bytes und eine available[]Maske von N Bits. Zum Zuweisen wird nach dem ersten verfügbaren Eintrag gesucht (Bittest, O (N), deterministische Obergrenze). Zum Aufheben der Zuordnung wird das verfügbare Bit (O (1)) gesetzt. malloc(X)rundet X auf den nächstgrößeren Wert von M auf, um den richtigen Pool auszuwählen.

Dies ist möglicherweise nicht sehr effizient, insbesondere wenn Sie zwischen N und M wählen. Und wenn Sie zu niedrig wählen, kann Ihr Programm fehlschlagen. Die Grenzwerte für N und M können jedoch niedriger sein als für ein gleichwertiges Programm ohne dynamische Speicherzuweisung.

MSalters
quelle
Der zyklische Puffer ist eine Variation dieses Allokators. Er kann zu Beginn der Ausführung sogar mit einem einzigen Malloc zugewiesen werden. Je nach Kontext gibt es andere Mutationen. Wenn Sie im Voraus wissen, dass Sie N verschiedene Puffergrößen benötigen, können Sie einen erstellen Allokator, der effizienter ist.
Rsf
1
Ein alternativer Ansatz zur Verwendung einer Bitmaske für einen Poolkollektor besteht in der Verwendung einer verknüpften Liste mit O (1) -Zuweisung und Freigabe. Solange der Code niemals versucht, mehr Puffer einer bestimmten Größe zuzuweisen, als im Pool vorhanden sind, ist das Timing abgesehen von Caching-Problemen vollständig deterministisch.
Supercat
1
Der allgemeinere Fall besteht darin, die Zuweisungen im Voraus vorzunehmen, bevor deterministisches Verhalten erforderlich ist. Wie der Speicher, den dieser Pool-Allokator benötigt :)
Hans Passant
Ich bin hier auf der Mission, ein scheinbar weit verbreitetes Missverständnis unter eingebetteten Ingenieuren zu brechen, dass die Speicherzuweisung beliebiger Größe (wie in malloc()Blöcken fester Größe) von Natur aus nicht zeitdeterministisch ist oder zu einer unbegrenzten Fragmentierung führen kann. Wie zum Beispiel in "Timing-Predictable Memory Allocation in harten Echtzeitsystemen" [Herter 2014] gezeigt, existieren vorhersagbare und effiziente Algorithmen, von denen jedoch selten gesprochen wird. Ich habe hier eine von ca. 500 Codezeilen für ein eingebettetes Echtzeitsystem implementiert, an dem ich beteiligt war: github.com/pavel-kirienko/o1heap
Pavel Kirienko
21

Nichts im C11- Standard oder in n1570 sagt, dass dies mallocdeterministisch ist (oder nicht); und auch keine andere Dokumentation wie malloc (3) unter Linux. Übrigens sind viele mallocImplementierungen freie Software .

Aber mallockann (und tut) fehlschlagen, und seine Leistung ist nicht bekannt (ein typischer Aufruf mallocauf meinem Desktop würde praktisch weniger als eine Mikrosekunde dauern, aber ich könnte mir seltsame Situationen vorstellen, in denen es viel länger dauern könnte, vielleicht viele Millisekunden bei einer sehr geladenen Computer; lesen Sie über das Verprügeln ). Und mein Linux-Desktop verfügt über ASLR (Address Space Layout Randomization), sodass das zweimalige Ausführen desselben Programms unterschiedliche mallocAdressen ergibt (im virtuellen Adressraum des Prozesses). Übrigens ist hier eine deterministische (unter bestimmten Annahmen, die Sie ausarbeiten müssen), aber praktisch nutzlose mallocImplementierung.

Determinismus bedeutet, dass das zweimalige Ausführen eines Programms zum exakt gleichen Ausführungspfad führt

Dies ist in den meisten eingebetteten Systemen praktisch falsch, da sich die physische Umgebung ändert. Beispielsweise kann die Software, die einen Raketentriebwerk antreibt, nicht erwarten, dass der Schub, der Luftwiderstand oder die Windgeschwindigkeit usw. von einem Start zum nächsten genau gleich sind.

(Ich bin also überrascht, dass Sie glauben oder wünschen, dass Echtzeitsysteme deterministisch sind; sie sind es nie! Vielleicht interessiert Sie WCET , das aufgrund von Caches immer schwieriger vorherzusagen ist. )

Übrigens implementieren einige "Echtzeit" - oder "eingebettete" Systeme ihre eigenen malloc(oder eine Variante davon). C ++ - Programme können ihre Allokatoren haben , die von Standardcontainern verwendet werden können . Siehe auch dies und das usw. usw. .....

Auf hoher Ebene eingebetteter Software (denken Sie an ein autonomes Automobil und seine Planungssoftware ) werden zwar Heap-Zuweisungen und möglicherweise sogar Speicherbereinigungstechniken (von denen einige "in Echtzeit" ausgeführt werden) verwendet, sie werden jedoch im Allgemeinen nicht als sicherheitskritisch angesehen.

Basile Starynkevitch
quelle
6
Ich denke, OP wollte sagen, dass das zweimalige Ausführen eines Programms mit genau denselben Eingaben zu demselben Ausführungspfad oder demselben beobachtbaren Verhalten führen sollte (oder welche andere Definition auch immer bevorzugt wird).
Toby Speight
Aber "beobachtbares Verhalten" ist subjektiv (was ist mit dem Debuggen printfmit dem %pErgebnis von malloc) und kann zu heftigen Diskussionen führen
Basile Starynkevitch
Ein Planer für ein autonomes Fahrzeug (oder eine andere sicherheitskritische Fahrzeugsoftware) verwendet keine Heap-Zuordnung oder Speicherbereinigung. Die dynamische Speicherzuweisung ist nach den MISRA- Regeln verboten .
Dasdingonesin
Ich habe Planung im Sinne der KI verwendet. Alle AI-Software für die Planung verwendet die Heap-Zuweisung (und die meisten von ihnen verwenden die Garbage Collection und sind in AI-Sprachen auf sehr hohem Niveau codiert, z. B. Lisp, Prolog usw.). Natürlich sind sie keine sicherheitskritischen Schichten solcher Systeme
Basile Starynkevitch
12

tl; dr: Es ist nicht so, dass die dynamische Speicherzuweisung von Natur aus nicht deterministisch ist (wie Sie es anhand identischer Ausführungspfade definiert haben). Es ist so, dass es Ihr Programm im Allgemeinen unvorhersehbar macht . Insbesondere können Sie nicht vorhersagen, ob der Allokator angesichts einer beliebigen Folge von Eingaben ausfallen könnte.

Sie könnten einen nicht deterministischen Allokator haben. Dies ist außerhalb Ihrer Echtzeitwelt üblich, in der Betriebssysteme beispielsweise die Randomisierung des Adresslayouts verwenden. Das würde Ihr Programm natürlich nicht deterministisch machen.

Dies ist jedoch kein interessanter Fall. Nehmen wir also einen perfekt deterministischen Allokator an: Dieselbe Reihenfolge von Zuweisungen und Freigaben führt immer zu denselben Blöcken an denselben Standorten, und diese Zuweisungen und Freigaben haben immer eine begrenzte Laufzeit.

Jetzt kann Ihr Programm deterministisch sein: Der gleiche Satz von Eingaben führt zu genau dem gleichen Ausführungspfad.

Das Problem ist, dass Sie beim Zuweisen und Freigeben von Speicher als Reaktion auf Eingaben nicht vorhersagen können, ob eine Zuweisung jemals fehlschlagen wird (und ein Fehler ist keine Option).

Erstens könnte Ihr Programm Speicher verlieren. Wenn es also auf unbestimmte Zeit ausgeführt werden muss, schlägt eine Zuordnung möglicherweise fehl.

Aber selbst wenn Sie nachweisen können, dass keine Lecks vorhanden sind, müssen Sie wissen, dass es niemals eine Eingabesequenz gibt, die mehr Speicher als verfügbar erfordern könnte.

Aber selbst wenn Sie nachweisen können, dass das Programm niemals mehr Speicher benötigt als verfügbar ist, kann der Allokator abhängig von der Reihenfolge der Zuweisungen und Freigaben den Speicher fragmentieren und somit möglicherweise keinen zusammenhängenden Block finden, um eine Zuordnung zu erfüllen, obwohl Insgesamt ist genügend freier Speicher vorhanden.

Es ist sehr schwierig zu beweisen, dass es keine Folge von Eingaben gibt, die zu einer pathologischen Fragmentierung führen.

Sie können Allokatoren entwerfen, um sicherzustellen, dass keine Fragmentierung auftritt (z. B. durch Zuweisen von Blöcken mit nur einer Größe). Dies stellt jedoch eine erhebliche Einschränkung für den Anrufer dar und erhöht möglicherweise den aufgrund der Verschwendung erforderlichen Speicherplatz. Und der Anrufer muss immer noch nachweisen, dass es keine Lecks gibt und dass unabhängig von der Reihenfolge der Eingaben eine zufriedenstellende Obergrenze für den Gesamtspeicher erforderlich ist. Diese Belastung ist so hoch, dass es tatsächlich einfacher ist, das System so zu gestalten, dass es keine dynamische Speicherzuweisung verwendet.

Adrian McCarthy
quelle
Das OP erwähnt Weltraumanwendungen (hohe Zuverlässigkeit) und Mikrocontroller-basierte Anwendungen. Das wirklich große Problem für diese ist die Heap-Fragmentierung und die unerwarteten Zuordnungsfehler, die auftreten können. Die Wahrscheinlichkeit, dass diese Art von Fehler auftritt, ist für die auf einem Mikrocontroller verfügbaren kleinen Speicherplätze hoch. Um dies zu verhindern, sollte der gesamte Speicher statisch zugewiesen und die maximale Stapelauslastung sorgfältig überwacht werden.
20.
10

Bei Echtzeitsystemen muss das Programm bestimmte Rechen- und Speicherbeschränkungen unabhängig vom verwendeten Ausführungspfad strikt einhalten (der je nach Eingabe immer noch erheblich variieren kann). Was bedeutet die Verwendung der generischen dynamischen Speicherzuweisung (z. B. malloc / new) in diesem Zusammenhang? Dies bedeutet, dass der Entwickler irgendwann nicht in der Lage ist, den genauen Speicherverbrauch zu bestimmen, und es unmöglich ist zu sagen, ob das resultierende Programm die Anforderungen sowohl an den Speicher als auch an die Rechenleistung erfüllen kann.

user7860670
quelle
4
Nun, das Dekomprimieren derselben komprimierten Datei führt immer zum gleichen Ergebnis, aber das Vorschlagen, das unkomprimierte Ergebnis zu speichern, verfehlt den Punkt der Dateikomprimierung;). Im Ernst, Routenplaner sind ein bekanntes Beispiel für vollständig deterministische Programme mit einem kleinen Eingaberaum (Anfangs- und Endpunkt), dessen Ergebnismatrix viel zu groß ist, um gespeichert zu werden.
MSalters
1
Dies scheint die gestellte Frage nicht zu beantworten. es beantwortet eine andere Frage. Zur Erinnerung lautete die Frage: "Macht die Verwendung des Heaps ein Programm nicht deterministisch?" Dies beantwortet diese Frage nicht. Es könnte die Frage beantworten, ob die Verwendung des Heaps in Echtzeitsystemen problematisch ist, aber das ist eine andere Frage.
DW
7

Ja, das ist richtig. Für die Art der Anwendungen, die Sie erwähnen, muss alles, was auftreten kann, detailliert angegeben werden. Das Programm muss das Worst-Case-Szenario gemäß Spezifikation behandeln und genau so viel Speicher reservieren, nicht mehr und nicht weniger. Die Situation, in der "wir nicht wissen, wie viele Eingaben wir erhalten", existiert nicht. Das Worst-Case-Szenario wird mit festen Zahlen angegeben.

Ihr Programm muss in einem Sinne deterministisch sein, dass es alles bis zum schlimmsten Fall verarbeiten kann.

Der eigentliche Zweck des Heaps besteht darin, mehreren nicht verwandten Anwendungen die gemeinsame Nutzung des RAM-Speichers zu ermöglichen, z. B. auf einem PC, auf dem die Anzahl der ausgeführten Programme / Prozesse / Threads nicht deterministisch ist. Dieses Szenario existiert in einem Echtzeitsystem nicht.

Darüber hinaus ist der Heap seiner Natur nach nicht deterministisch, da Segmente im Laufe der Zeit hinzugefügt oder entfernt werden.

Weitere Informationen finden Sie hier: https://electronics.stackexchange.com/a/171581/6102

Lundin
quelle
2
"deterministisch in dem Sinne, dass es alles bis zum schlimmsten Fall bewältigen kann" - Das bedeutet das Wort deterministisch nicht. Nicht alles, was schlechte Technik ist, ist nicht deterministisch.
DW
@DW Wenn Sie angeben, dass Ihr Programm in der Lage sein soll, bis zu 100 Dinge zu verarbeiten, entwerfen Sie dafür und erwarten deterministisches Verhalten für alle Fälle bis zu 100. Wenn Sie die angegebenen Grenzen überschreiten, sind alle Wetten ungültig und das Ergebnis ist unbestimmt . Dies ist eigentlich das, was deterministisch bedeutet. Eine Alternative wäre, keine Obergrenze festzulegen und den Heap zuzuweisen. Der Punkt, an dem das Programm durcheinander geraten wird, kann dann nicht leicht bestimmt werden. Dies hängt von der Größe des Heapspeichers, der Fragmentierung des Heapspeichers und vielen anderen Faktoren ab. Ebenso, wenn Sie "eine beliebige Menge an Eingaben" anstelle eines deterministischen Maximums zulassen.
Lundin
5

Selbst wenn Ihr Heap-Allokator ein wiederholbares Verhalten aufweist (dieselbe Zuordnungssequenz und freie Aufrufe ergeben dieselbe Blocksequenz, daher (hoffentlich) denselben internen Heap-Status), kann der Status des Heaps drastisch variieren, wenn die Aufrufsequenz geändert wird Dies kann möglicherweise zu einer Fragmentierung führen, die auf unvorhersehbare Weise zu Speicherzuordnungsfehlern führt.

Der Grund, warum die Heap-Zuweisung in eingebetteten Systemen völlig verboten ist, insb. Bei geschäftskritischen Systemen wie Leit- oder Lebenserhaltungssystemen für Flugzeuge oder Raumfahrzeuge gibt es keine Möglichkeit, alle möglichen Variationen in der Reihenfolge der malloc / freien Anrufe zu testen, die als Reaktion auf intrinsisch asynchrone Ereignisse auftreten können.

Die Lösung besteht darin, dass für jeden Handler ein Speicher für seinen Zweck reserviert wird und es keine Rolle mehr spielt (zumindest was die Speichernutzung betrifft), in welcher Reihenfolge diese Handler aufgerufen werden.

chqrlie
quelle
3

Das Problem bei der Verwendung von Heap in Echtzeit-Software besteht darin, dass Heap-Zuweisungen fehlschlagen können. Was machst du, wenn dir der Haufen ausgeht?

Sie sprechen von Weltraumanwendungen. Sie haben ziemlich harte No-Fail-Anforderungen. Sie dürfen keine Möglichkeit haben, Speicher zu verlieren, sodass nicht genügend Code für den abgesicherten Modus vorhanden ist. Du darfst nicht umfallen. Sie dürfen keine Ausnahmen auslösen, die keinen catch-Block haben. Sie haben wahrscheinlich kein Betriebssystem mit geschütztem Speicher, sodass eine abstürzende Anwendung theoretisch alles ausschalten kann.

Sie möchten wahrscheinlich überhaupt keinen Heap verwenden. Die Vorteile überwiegen nicht die Gesamtkosten des Programms.

Nicht deterministisch bedeutet normalerweise etwas anderes, aber in diesem Fall ist es am besten, wenn das gesamte Programmverhalten vollständig vorhersehbar sein soll.

Joshua
quelle
2

Stellen Sie Integrity RTOS von GHS vor:

https://www.ghs.com/products/rtos/integrity.html

und LynxOS:

http://www.lynx.com/products/real-time-operating-systems/lynxos-178-rtos-for-do-178b-software-certification/

LynxOS und Integrity RTOS gehören zu der Software, die in Weltraumanwendungen, Raketen, Flugzeugen usw. verwendet wird, da viele andere nicht von Behörden (z. B. FAA) genehmigt oder zertifiziert sind.

https://www.ghs.com/news/230210r.html

Um die strengen Kriterien von Weltraumanwendungen zu erfüllen, bietet Integrity RTOS tatsächlich eine formale Überprüfung, dh eine mathematisch erprobte Logik, dass sich ihre Software gemäß den Spezifikationen verhält.

Unter diesen Kriterien, um von hier aus zu zitieren:

https://en.wikipedia.org/wiki/Integrity_(operating_system)

und hier:

Green Hills Integrity Dynamische Speicherzuordnung

ist das:

Geben Sie hier die Bildbeschreibung ein

Ich bin kein Spezialist für formale Methoden, aber möglicherweise besteht eine der Anforderungen für diese Überprüfung darin, die Unsicherheiten im Timing zu beseitigen, die für die Speicherzuweisung erforderlich sind. In RTOS sind alle Ereignisse genau Millisekunden voneinander entfernt geplant. Und die dynamische Speicherzuweisung hat immer ein Problem mit dem erforderlichen Timing.

Mathematisch müssen Sie wirklich beweisen, dass alles funktioniert, und zwar unter den grundlegendsten Annahmen über das Timing und die Größe des Speichers.

Und wenn Sie an die Alternativen zum Heap-Speicher denken: statischer Speicher . Die Adresse ist fest, die zugewiesene Größe ist fest. Die Position im Speicher ist fest. Es ist also sehr einfach, über ausreichende Speicherkapazität, Zuverlässigkeit, Verfügbarkeit usw. nachzudenken.

Peter Teoh
quelle
1
Technisch gesehen ist es als geschlossenes System deterministisch, aber auch chaotisch, dh. unmöglich vorherzusagen.
John Wu
2

Kurze Antwort

Es gibt einige Auswirkungen auf die Datenwerte oder deren statistische Unsicherheitsverteilungen, z. B. eines Triggerszintillatorgeräts der ersten oder zweiten Ebene, die sich aus der nicht reproduzierbaren Zeit ergeben können, auf die Sie möglicherweise warten müssen malloc/free.

Das Schlimmste ist, dass sie weder mit der Hardware noch mit dem Zustand des Speichers (und seiner Geschichte) mit dem physikalischen Phänomen zusammenhängen.

In diesem Fall besteht Ihr Ziel darin, die ursprüngliche Abfolge von Ereignissen aus den von diesen Fehlern betroffenen Daten zu rekonstruieren. Die rekonstruierte / erratene Sequenz wird ebenfalls von Fehlern beeinflusst. Nicht immer wird diese Iteration zu einer stabilen Lösung führen. es wird nicht gesagt, dass es das richtige sein wird; Ihre Daten sind nicht mehr unabhängig ... Sie riskieren einen logischen Kurzschluss ...

Längere Antwort

Sie erklärte : „Ich nicht in der Lage war , die Richtigkeit dieser Aussage zu überprüfen , wenn Leute mir sagen , dass“ .
Ich werde versuchen, Ihnen eine rein hypothetische Situation / Fallstudie zu geben.

Stellen wir uns vor, Sie beschäftigen sich mit einem CCD oder mit einigen Szintillator-Triggern der 1. und 2. Ebene auf einem System, das Ressourcen sparen muss (Sie befinden sich im Weltraum).
Die Erfassungsrate wird so eingestellt, dass der Hintergrund auf x%dem liegt MAXBINCOUNT.

  • Es gibt einen Ausbruch, Sie haben eine Spitze in der Zählung und einen Überlauf im Behälterzähler.
    Ich möchte alles: Sie wechseln zur maximalen Erfassungsrate und beenden Ihren Puffer.
    Sie gehen, um mehr Speicher freizugeben / zuzuweisen, während Sie den zusätzlichen Puffer beenden.
    Was wirst du tun?

    1. Sie werden die Gegen halten das Risiko , Überlauf (die zweite Ebene wird versuchen , richtig das Timing der Datenpakete zu zählen) , aber in diesem Fall gehen Sie zu unterschätzen die Zählungen für diesen Zeitraum?
    2. Sie werden den Zähler stoppen, der ein Loch in die Zeitreihe einführt ?

    Beachten Sie, dass:

    • Wenn Sie auf die Zuordnung warten, verlieren Sie den Übergang (oder zumindest seinen Anfang).
    • Was auch immer Sie tun, es hängt vom Zustand Ihres Gedächtnisses ab und ist nicht reproduzierbar.
  • Stattdessen ist das Signal jetzt um die maxbincountmaximal von Ihrer Hardware zulässige Erfassungsrate variabel , und das Ereignis ist länger als gewöhnlich.
    Sie beenden den Raum und bitten um mehr ... währenddessen haben Sie das gleiche Problem wie oben.
    Überlauf und systematische Peaks zählen Unterschätzung oder Löcher in der Zeitreihe?

Lassen Sie uns eine zweite Ebene verschieben (es kann sich auch um den Auslöser der ersten Ebene handeln).

Von Ihrer Hardware erhalten Sie mehr Daten, als Sie lagern oder übertragen können.
Sie müssen die Daten zeitlich oder räumlich gruppieren (2x2, 4x4, ... 16x16 ... 256x256 ... Pixelskalierung ...).

Die Unsicherheit aus dem vorherigen Problem kann die Fehlerverteilung beeinflussen .
Es gibt CCD-Einstellungen, für die Sie die Pixel des Rahmens mit einer Anzahl nahe an der haben maxbincount(dies hängt davon ab, "wo" Sie besser sehen möchten).
Jetzt können Sie auf Ihrem CCD oder einem einzelnen großen Punkt mit der gleichen Gesamtzahl von Zählungen, aber mit einer anderen statistischen Unsicherheit (dem Teil, der durch die Wartezeit eingeführt wird) duschen ...

Wenn Sie beispielsweise ein Lorentz-Profil erwarten, können Sie dessen Faltung mit einem Gauß-Profil (Voigt) erhalten, oder wenn das zweite mit einem schmutzigen Gauß- Profil wirklich dominant ist ...

Hastur
quelle
-3

Es gibt immer einen Kompromiss. Die Ausführungsumgebung des Programms und die von ihm ausgeführten Aufgaben sollten die Grundlage für die Entscheidung sein, ob HEAP verwendet werden soll oder nicht.

Das Heap-Objekt ist effizient, wenn Sie die Daten für mehrere Funktionsaufrufe freigeben möchten. Sie müssen nur den Zeiger übergeben, da auf den Heap global zugegriffen werden kann. Es gibt auch Nachteile. Einige Funktionen können diesen Speicher freigeben, aber auch an anderen Stellen sind möglicherweise einige Referenzen vorhanden.

Wenn der Heap-Speicher nach Abschluss seiner Arbeit nicht freigegeben wird und das Programm weiterhin mehr Speicher zuweist, geht HEAP irgendwann der Speicher aus und beeinflusst den deterministischen Charakter des Programms.

Naresh
quelle
1
"Sie müssen nur den Zeiger übergeben, da auf den Heap global zugegriffen werden kann." Und das ist anders als .dataund .bsswie ...?
Lundin
5
Man kann globale Stapelvariablen erstellen ... wo liegt das Problem dabei? Sie können auch zwischen Funktionen übergeben werden.
Der Quantenphysiker
2
Dies scheint die gestellte Frage nicht zu beantworten. es beantwortet eine andere Frage. Zur Erinnerung lautete die Frage: "Macht die Verwendung des Heaps ein Programm nicht deterministisch?" Dies beantwortet diese Frage nicht. Es könnte die Frage beantworten, ob die Verwendung des Heaps in Echtzeitsystemen eine gute Idee ist, aber das ist eine andere Frage. Der letzte Satz geht in diese Richtung, aber Sie sagen nicht, wie er sich auf den deterministischen Charakter des Programms auswirkt oder warum, und beantworten die Frage nicht.
DW