Forum: Mikrocontroller und Digitale Elektronik malloc/free vs. statische Variablen auf µC


von Martin (Gast)


Lesenswert?

Hallo,

ich habe mal eine allgemeine Frage. Was bevorzugt ihr auf einem µC für 
eine Technik bei Benutzung von Strukturen, Arrays usw. ? Erzeugt ihr 
statische Arrays (also array[100]) oder arbeitet ihr fleißig mit 
malloc/free? Wie gesagt, nicht auf einem PC sondern einem µC.
Funktioniert malloc und free genauso zuverlässig oder ist dies auf dem 
µC mit Nachteilen behaftet.

Danke Martin

von I_ H. (i_h)


Lesenswert?

Wenn es kein ARM oder so mit viel Ram ist, solltest du malloc/free 
vermeiden wo möglich.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich weiß, dass es viele Gegner von malloc() in einer Controller-
Umgebung gibt.  Das Hauptproblem ist: wenn du mit den Ressourcen
am Ende bist, ist es nahezu egal, ob deine statisch vorbelegten
Ressourcen nicht mehr reichen oder der dynamische Speicher alle
ist: sehr oft gibt es dafür einfach keinen vernünftigen Ausweg mehr.
Was dann passieren kann/darf/soll, darüber muss man sich von
vornherein im Klaren sein.

Ich habe gestern eine langjährige Implementierung mit statischen
Tabellen auf malloc() umgestellt, weil mir die Bugs, die beim
notwendigen Umsortieren der statischen Einträge immer wieder
auftraten, nunmehr so sehr auf die Füße gefallen waren, dass ich
einfach keine Lust mehr hatte, dort nochmals Aufwand reinzusetzen.
Was soll ich sagen?  Zwei Übersetzungsgänge zum Ausbügeln der
Syntaxfehler, einen Versuchslauf, bei dem sich nach 5 Sekunden ein
Implementierungsfehler gezeigt hat -- und jetzt laufen meine
Stresstests hier durch, an denen ich vorher eine Woche mit dem
Logicanalyzer herum debuggt habe, um dann doch nur festzustellen,
dass das besagte Subsystem offenbar kaputt ist...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

p.s.: Mein Lieblingsvergleich von malloc zu statischer Belegung ist der
zwischen Ethernet und Token Ring.  Der Token Ring ist die ,,reine
Lehre'': alles ist deterministisch, und bis das Medium wirklich
komplett gesättigt ist, geht alles ganz geregelt seinen Gang.  Bei
Ethernet werden Dinge dem Zufall überlassen, und ab 95 % Auslastung
bricht es dann langsam ein.  Nur: für die 5 %, die man den Token Ring
dann noch besser benutzen kann, bezahlt man halt einen viel höheren
Preis, da die ganze Verwaltung aufwändig ist.  (Und wenn man die 100 %
erreicht hat, muss man sich auch dort dann nach mehr Ressourcen
umsehen.)

Welches der beiden Protokolle überlebt hat, ist mittlerweile ja
ziemlich klar...

von Hektor (Gast)


Lesenswert?

Ich: absoluter Gegner von malloc auf nem uC!

Bei statischen Variablen siehst du bei der Entwicklung ob der Speicher 
noch reicht, bei Verwendung von malloc weißt du das nie so genau und 
fehler zeigen sich unter u. erst im Feld. Außerdem brauchst du mehr Code 
weil du immer prüfen musst, ob der Speicher geholt werden konnte. 
Außerdem hilft es auch beim debuggen wenn eine Variable immer an der 
gleichen Adresse steht.

von Martin (Gast)


Lesenswert?

Hallo,

interessant wie dieses Thema anscheinend polarisiert.

Wenn ich so die Antwort von Hektor lese, tendiere ich zur statischen 
Variante, lese ich die von Jörg, dann diese.

Die Wahl des Richtigen ist wohl nicht ganz so einfach.

Gruss
Martin

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Auf einem µC ist malloc nun mal sehr schmerzlich

-- es belegt selbst RAM für die Verwaltung
-- es belegt mehr Programmspeicher
-- es braucht mehr Zeit
-- es ist praktisch nicht statisch analysierbar und deshalb in 
sicherheitskritischen Anwendungen kaum oder nicht gesehen.

Erste drei Punkte treffen für kleine µC zu, während in 
sicherheitskritischen Anwendungen größere µC zum Einsatz kommen. Unter 
der Motorhaube Deines PKW gibt es zum Beispiel kein malloc.

In manchen Fällen kann alloca eine Alternative sein, also Code in der 
Richtung
1
void foo (size_t size)
2
{
3
   type_t var[size];
4
   ...
5
}

Vom Overhead ist das günstiger (ebenso von der statischen Analyse her), 
aber die so erhaltenen Speicherbereiche sind eben nicht dynamisch 
sondern auto (findet sich aber ebensowenig im Auto).

von Peter D. (peda)


Lesenswert?

Jörg Wunsch wrote:

> Was soll ich sagen?  Zwei Übersetzungsgänge zum Ausbügeln der
> Syntaxfehler, einen Versuchslauf, bei dem sich nach 5 Sekunden ein
> Implementierungsfehler gezeigt hat -- und jetzt laufen meine
> Stresstests hier durch, an denen ich vorher eine Woche mit dem
> Logicanalyzer herum debuggt habe, um dann doch nur festzustellen,
> dass das besagte Subsystem offenbar kaputt ist...

Soll das jetzt heißen, daß malloc die Fehlersuche vereinfacht?

Ich würde eher sagen, die Beschäftigung mit dem Programm beim Umstellen 
hat den Blick geschärft.
Es könnte also auch sein, daß man bei einem anderen Programm beim 
Umstellen von malloc auf Tabelllen den Fehler findet.

Das passiert nicht selten, man sitzt tagelang vor einem fremden 
Programm, wie das Kaninchen vor der Schlange.
Und erst, wenn man sich richtig tief in die Suppe reinkniet, findet man 
den Fehler.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. wrote:

> Auf einem µC ist malloc nun mal sehr schmerzlich
>
> -- es belegt selbst RAM für die Verwaltung

Das ist aber deutlich weniger als das, was du sonst als statische
Vorbelegungen von Ressourcen brauchst, da du ja immer ,,für alle
Fälle'' gewappnet sein musst.  In der avr-libc sind es beispielsweise
gerade mal 10 Bytes.

In meinem genannten Falle brauche ich diese 10 Bytes sowie unter
Stressbedingungen ca. 40...50 Bytes an Daten (mit dem Debugger
analysiert).  Die frühere statische Lösung besaß zwei Arrays mit
mit insgesamt 224 Bytes.

> -- es belegt mehr Programmspeicher

Ja, auf jeden Fall.

> -- es braucht mehr Zeit

Jein.  Kommt drauf an.  In meinem oben genannten Fall habe ich es
nicht analysiert, ist aber gut möglich, dass es dort weniger Zeit
braucht als die ständige Umsortiererei der statischen Tabellen
zuvor.  Wenn nämlich ein Eintrag abgearbeitet ist, kann ich ihn
einfach ,,wegwerfen'', um die Entsorgung kümmert sich die
Bibliothek.

> -- es ist praktisch nicht statisch analysierbar und deshalb in
> sicherheitskritischen Anwendungen kaum oder nicht gesehen.

Ja, klar.  Aber wenn's sicherheitskritisch ist, sind die höheren
Kosten für den Ressourcen-Mehrverbrauch einer voll statischen Lösung
normalerweise unproblematisch.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Soll das jetzt heißen, daß malloc die Fehlersuche vereinfacht?

Nein, das Problem war schon immer dynamischer Natur und dadurch
mit dynamisch erzeugten Listen viel überschaubarer zu
implementieren.

> Es könnte also auch sein, daß man bei einem anderen Programm beim
> Umstellen von malloc auf Tabelllen den Fehler findet.

Die vorige Implementierung hat bereits genügend Entwicklungskosten
hier für ihre Wartung geschluckt, sowohl seitens desjenigen, der
das Original implementiert hat als auch seitens anderer Entwickler.
Sie war (auf Grund der dynamischen Natur des zu Grunde liegenden
Problems) so schwer mit all ihren möglichen Randbedingungen und
möglichen race conditions zu überschauen, dass sie immer wieder
Bugs gezeigt hat.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

p.s.: Peter, ich will hier überhaupt nicht in Abrede stellen, dass
man eine Implementierung ohne malloc() hätte finden können, die
bugfrei funktioniert.  Die Implementierung mit malloc() war aber nach
all den damit gemachten Erfahrungen der letzten Jahre die in jeder
Hinsicht ökonomischere, und sie hat (für uns) keinerlei Nachteil.

von Peter D. (peda)


Lesenswert?

Jörg Wunsch wrote:
> Die Implementierung mit malloc() war aber nach
> all den damit gemachten Erfahrungen der letzten Jahre die in jeder
> Hinsicht ökonomischere, und sie hat (für uns) keinerlei Nachteil.

Ich kenne jetzt Deine Anwendung nicht.
Es gibt bestimmt für jede Programmierweise auch eine entsprechende 
Anwendung, für die diese optimal ist.

Ich hatte ja mal einen Scheduler geschrieben, der auch Einträge 
hinzufügen, entfernen und umsortieren muß.
Allerdings sortiert er nicht wirklich um, sondern ändert nur die 
Verkettung.
Vielleicht wäre das auch ein Kandidat für malloc.


Peter

von Simon K. (simon) Benutzerseite


Lesenswert?

Malloc/free wird dann problematisch, wenn es an zwei Stellen eingesetzt 
wird, mit jeweils unterschiedlicher Blockgröße. Dann kann es nämlich 
passieren, dass der Speicher (durch den Aufruf mit der kleineren 
Blockgröße) so fragmentiert ist, dass möglicherweise noch 50% des RAMs 
frei sind, aber kein größerer Block mehr alloziert werden kann. (Außer 
man betreibt einen Garbage Collector o.ä., aber das wäre dann wirklich 
zuviel Overhead)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Ich kenne jetzt Deine Anwendung nicht.

Ist eine timer queue.

> Vielleicht wäre das auch ein Kandidat für malloc.

Ja, wenn sich Verkettungen dynamisch ändern können, ist das häufig
damit einfacher abzubilden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Simon K. wrote:

> Malloc/free wird dann problematisch, wenn es an zwei Stellen eingesetzt
> wird, mit jeweils unterschiedlicher Blockgröße. Dann kann es nämlich
> passieren, dass der Speicher (durch den Aufruf mit der kleineren
> Blockgröße) so fragmentiert ist, dass möglicherweise noch 50% des RAMs
> frei sind, aber kein größerer Block mehr alloziert werden kann. (Außer
> man betreibt einen Garbage Collector o.ä., aber das wäre dann wirklich
> zuviel Overhead)

Klar, Speicherfragmentierung ist immer ein mögliches Problem.  Wenn
beide Ereignisse aber einigermaßen zufällig zueinander sind, dann
wird das sich im Betrieb irgendwo einpegeln und danach nicht weiter
fragmentieren.

Wenn man das Ganze während der Probephase mit einem Debugger
beobachten kann, dann kann man anhand der höchsten je durch malloc()
belegten Speicheradresse relativ einfach feststellen, ob sich da
noch was aufschaukelt oder nicht.

Aber zurück zur statischen Variante: in aller Regel werden dieser
in solchen worst-case-Szenarien die Ressourcen bereits viel früher
ausgegangen sein, wo die dynamische Variante durch ihre größere
Flexibilität noch Reserven hat.  Sie kann nämlich den Speicher für
Ressource A nie auch alternativ für Ressource B benutzen, während
die dynamische Variante das erst einmal kann.

Ich hoffe, ich klinge jetzt nicht so, als wäre malloc() das
Allheilmittel schlechthin. ;-)  Das ist es ganz gewiss auch nicht.
Jedem Problem seine Lösung.  malloc() kann es halt durch seine
Flexibilität erlauben, dass eine bestimmte Applikation im normalen
Betrieb die Ressource RAM besser benutzt, wenn die Anforderungen
an diese Ressource nicht vorhersagbar sind und eher zufällig
auftauchen.  In derartigen Situationen muss man aber immer (auch
bei statischer Allokierung) den Fall abdecken, dass die Ressourcen
den Anforderungen nicht genügen und einplanen, wie man in diesem
Falle vorgeht.

Wenn alles rein statisch und zur Compilezeit bekannt ist, dann hat
malloc() natürlich absolut keinen Sinn.  Wieder andere Probleme
können sich gut mit dem bereits beschriebenen alloca() lösen lassen,
dass die Allokation auf dem Stack erledigt.

von Simon K. (simon) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
> Wenn alles rein statisch und zur Compilezeit bekannt ist, dann hat
> malloc() natürlich absolut keinen Sinn.  Wieder andere Probleme
> können sich gut mit dem bereits beschriebenen alloca() lösen lassen,
> dass die Allokation auf dem Stack erledigt.

Das sollte man so mal festhalten, da das den meisten Leuten gar nicht so 
bewusst ist :-)

Kann man eigentlich irgendwo die malloc-Implementierung von der avrlibc 
nachschauen?

PS: Habs schon:
http://cvs.savannah.gnu.org/viewvc/avr-libc/libc/stdlib/malloc.c?revision=1.11&root=avr-libc&view=markup

von yalu (Gast)


Lesenswert?

Ich halte die dynamische Speicherverwaltung mit malloc, wie sie
üblicherweise implementiert ist, auf Systemen, wo mehr als etwa 20%
des RAM-Speichers genutzt werden, für ziemlich gefährlich. Ich hatt
aledings bisher keine µC-Anwendung, bei der ich einen dringenden
Bedarf nach malloc und free sah. Meist konnte man das Problem mit ein
paar zusätzlichen Code-Zeilen anders lösen.

Bei der üblichen Heap-Verwaltung ist auf Grund der Speicherfragmentie-
rung der theoretisch (über beliebig verteilte Datenblöcke) ermittelte
Worst-Case-Speicherbedarf meist ein Vielfaches größer als die
tatsächlich gespeicherte Datenmenge, d.h. der tatsächlich nutzbare
Anteil des Gesamtspeichers ist ziemlich gering. Praktische Test
erwecken oft den Eindruck, dass man den Speicher deutlich besser
nutzen kann, manchmal sogar zurecht. Aber wer garantiert, dass ein
Speicherproblem durch eine unwahrscheinliche Verkettung unglücklicher
Umstände nicht erst nach Monaten auftritt?

Hier im Forum tauchte einmal die Frage auf, wie man Stackbedarf von
C-Programmen abschätzt. Das ist auch schon schwierig, da aber die
Daten auf dem Stack "dicht" liegen, ist eine (ggf. nicht ganz
optimale) Worst-Case-Abschätzung noch ganz gut machbar.

Auch eine Heap-Verwaltung kann halbwegs überschaubar sein, wenn man
nicht einen universellen Algorithmus benutzt, sondern einige
Einschränkungen in Kauf nimmt.

Beispiel:

In grauer Vorzeit gab es eine Programmier- und Laufzeitumgebung namens
UCSD Pascal. Dort wurde der Heap wie ein Stack, also mit dichtliegen-
den Daten, verwaltet, es gab also keine Speicherfragmentierung. Da der
Heap von unten nach oben und Programmstack von oben nach unten wuchs,
konnte der Speicher wirklich bis aufs letzte Byte gefüllt werden,
bevor der Crash kam. Nachteil: Der Speicher konnte nur in umgekehrter
Reihenfolge der Allozierung wieder freigegeben werden. Die Abschätzung
des Platzbedarfs ist in diesem Fall nicht schwieriger als beim
Programmstack.

Anderes Beispiel:

Bei einfachen Anwendungen benötigt man vielleicht eine oder mehrere
dynamische verkettete Listen, deren Elemente aber alle die gleiche
Größe haben. In diesem Fall kann man sich eine einfache und sehr
effiziente Speicherverwaltung selber bauen: Man legt ein Array mit der
maximal zu erwartenden Anzahl von Elementen an. Die genutzten Elemente
werden entsprechend ihrer Reihenfolge in den Listen verzeigert, die
ungenutzten Elemente ebenfalls. Jedesmal, wenn ein neues Element
benötigt wird, wird einfach das erste Element der Ungenutzt-Liste in
eine der anderen Listen umgehängt, beim Freigeben eines Elements kommt
es zurück in die Ungenutzt-Liste. Die dabei enstehende Fragmentierung
ist unschädlich, weil auf Grund der einheitlichen Elementgröße jede
entstehende Lücke garantiert wieder genutzt werden kann. Da Allozieren
und Freigeben beide in konstanter Zeit ausgeführt werden, ist dieses
Verfahren sogar hart echtzeitfähig.

Ok, wahrscheinlich werden die meisten Standard-Speicherverwaltungen
bei Beschränkung auf gleichgroße Datenblöcke ähnlich gut
funktionieren. Um dessen sicher zu sein, muss man die verwendeten
Algorithmen aber erst analysieren.

von I_ H. (i_h)


Lesenswert?

Jörg Wunsch wrote:
> p.s.: Mein Lieblingsvergleich von malloc zu statischer Belegung ist der
> zwischen Ethernet und Token Ring.  Der Token Ring ist die ,,reine
> Lehre'': alles ist deterministisch, und bis das Medium wirklich
> komplett gesättigt ist, geht alles ganz geregelt seinen Gang.  Bei
> Ethernet werden Dinge dem Zufall überlassen, und ab 95 % Auslastung
> bricht es dann langsam ein.  Nur: für die 5 %, die man den Token Ring
> dann noch besser benutzen kann, bezahlt man halt einen viel höheren
> Preis, da die ganze Verwaltung aufwändig ist.  (Und wenn man die 100 %
> erreicht hat, muss man sich auch dort dann nach mehr Ressourcen
> umsehen.)
>
> Welches der beiden Protokolle überlebt hat, ist mittlerweile ja
> ziemlich klar...

Sei mit solchen Vergleichen lieber vorsichtig... ich hab hier noch ein 
Token am kreisen ;).

Die "Verwaltung" ist bei TokenRing viel einfacher als bei switched 
Ethernet, die MAU braucht nichtmal Strom! Da drinnen sitzen nur ein paar 
ordinäre Relais, die von den NICs geschaltet werden.

Bei Ethernet brauchst du in den Switches dagegen haufenweise Hardware 
und Prozessoren, um ähnlich gute Eigenschaften wie Tokenring zu 
erreichen. Bei Ethernet ohne switch (hub oder bnc) stößt du bei mehreren 
Teilnehmern schon bei 30% der Bruttodatenrate an die Kapazitätsgrenzen - 
mit Außreißern in den Latenzzeiten jenseits von gut und böse.

16mbit TokenRing hängt bei vielen Teilnehmern problemlos 100mbit 
Ethernet ab, wenn mit Hub statt Switch. Und so'n 30port Switch gibt's 
auch net für lau, TokenRing MAUs kannst du dagegen ohne negative 
Auswirkungen kaskadieren (ok, Hubs auch, Switches macht nur über Uplink 
Port mit >>100mbit Sinn).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

I_ H. wrote:

> 16mbit TokenRing hängt bei vielen Teilnehmern problemlos 100mbit
> Ethernet ab, wenn mit Hub statt Switch.

Sorry, aber das ist Quark.  Ein Ethernet bricht irgendwo bei 95 %
der Bruttodatenrate ein, davor läuft es einfach nur.  Ich habe lange
genug mit 10Mbit-Netzen gearbeitet, die bringen problemlos ihre
Datenrate.

Seit 100 Mbit/s wird Ethernet prinzipiell geswitcht.  OK, da gibt
es auch Unterschiede in der Qualität, die sich insbesondere im
Gesamtdurchsatz unterscheiden dürften, aber für die 10 Kröten eines
China-Billigswitches gab's beim TokenRing noch nicht mal das Token. ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

yalu wrote:

> Bei der üblichen Heap-Verwaltung ist auf Grund der Speicherfragmentie-
> rung der theoretisch (über beliebig verteilte Datenblöcke) ermittelte
> Worst-Case-Speicherbedarf meist ein Vielfaches größer als die
> tatsächlich gespeicherte Datenmenge, d.h. der tatsächlich nutzbare
> Anteil des Gesamtspeichers ist ziemlich gering.

Da du nach eigenen Behauptungen malloc() auf einem Controller noch
nie benutzt hast, würde ich dir hier einfach mal die Kompetenz
abstreiten.  Sicher kannst du einen pathologischen Fall konstruieren,
in dem das eintreten könnte, allerdings ist es dann die Frage, wie
viel wahrscheinlicher es ist, dass deine ganze Controllerapplikation
bspw. auf Grund eines Hardwarefehlers den Bach vorher runtergegangen
ist.

von I_ H. (i_h)


Lesenswert?

Nein, 100mbit Ethernet wird nicht immer geswitched, und nein, bei vielen 
Teilnehmern und einem zusammenhängenden Ethernet (Hub, kein Switch), 
bricht die Datenrate schon sehr weit vor 100% zusammen. Glaub's, es ist 
so. 95% könnte bei switched Ethernet der Fall sein, da hast du ja auch 2 
Teilnehmer pro Kanal, die beide gleichzeitig losplappern können.

Hubs benutzt man stellenweise auch heute noch, weil die Latenzzeiten 
deutlich niedriger als bei switched ethernet sind.


http://www.tu-chemnitz.de/informatik/RA/news/stack/kompendium/vortraege_97/ethernet/performance.html

"Bei 100Base-T ist ab einer Netzlast von 30 % mit einem massiven Anstieg 
der Antwortzeiten zu rechnen. Als Netzkonfiguration sind bei den 
Anwendungen Textverarbeitung und EMail bis zu 100 PCs und Drucker pro 
Ethernet-Segment akzeptabel; bei CAD/CAM max. 15 Stationen je Segment; 
bei Videokonferencing, 3D-Simulation, Multimedia max. 4 Stationen. - In 
der Praxis stehen höchstens 40 % der physikalischen Bandbreite zur 
Verfügung. (Vgl. Gateway 5/97: 42))"

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Der Anstieg der Latenz selbst wird von der TCP-Schicht normalerweise
ausgeglichen.  Auf unseren DSL-Leitungen haben wir auch deutlich
größere Latenzen als seinerzeit auf ISDN, willst du deshalb zu ISDN
zurück?

Die genannten Maximalzahlen beziehen sich auf den erzielbaren
Gesamtdurchsatz, ist natürlich klar, wenn du CAD/CAM-Anwendungen
(die vor 10 Jahren wohl auf einem Server gegen ein X-Terminal o.ä.
liefen) hast, die viel Grafik übers Netz schaufeln, dann ist das
Netz damit einfach gesättigt.  Das wäre aber dein toter Ring auch
(und dessen ,,schnelle'' 16-Mbit/s-Variante wäre sogar schon bei
der Hälfte der 30 % Last dicht, bei der bei dem 100-baseT gerade
mal die Latenz größer wird).

In der heutigen Welt ist das wohl vergleichbar mit 10 Windows-
Terminals, die alle gegen einen WinNT-Terminalserver laufen (aber
nicht Citrix nehmen, die haben es nämlich deutlich intelligenter
implementiert als X11).

von Peter (Gast)


Lesenswert?

@Jörg Wunsch

> Der Anstieg der Latenz selbst wird von der TCP-Schicht normalerweise
> ausgeglichen.  Auf unseren DSL-Leitungen haben wir auch deutlich
> größere Latenzen als seinerzeit auf ISDN, willst du deshalb zu ISDN
> zurück?

ja, manchmal schon. Warum lassen denn so viele leute speedpath auf der 
DSL-Leitung schalten?. Warum kommt denn VoIP mit der Sprachqualität 
nicht auf ISDN Qualität?. Bei DSL geht die latenz ja noch, bei UMTS und 
GRRS ist es nicht mehr schön über ssh zu arbeiten. War nicht in einer 
der Letzten CT's ein artikel über Industie-Ethernet dort ist auch das 
Hauptproblem die Latenz. Die Bandbreite ist heute wirklich nicht mehr 
das Problem aber eine geringe Latenz nicht so einfach zu erreichen.
Warum verschicken wir nicht unsere Daten nicht mit der Post(auf 
Festplatte) die Bandbreite ist doch dann auch sehr gut? (2Tage laufzeit, 
1Tbyte = 5Mbyte/s)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter wrote:

> Warum kommt denn VoIP mit der Sprachqualität
> nicht auf ISDN Qualität?

Weil die Anforderung voice nun einmal garantierte Bandbreite braucht,
und die gibt's ohne QOS einfach nicht.  Andersrum wieder hatte man
bei ISDN mehr oder weniger vergessen, ein Protokoll ohne
Bandbreitengarantie vorzusehen (nicht ganz, man hatte es nur als
Zugang zu einem PAD vorgesehen), damit hast du bei der Benutzung
für IP immer die volle Bandbreite bezahlt, egal ob du sie genutzt
hast oder nicht.

Ja, die Latenz spielt bei Telefonie auch eine Rolle, aber bei
vielen hochbandbreitigen Computerdaten nicht, und eine Bevorzugung
interaktiver Dienste gab's in Form von IPTOS auch schon lange.

Und nein, ohne QOS mag ich VoIP nicht haben, zumindest nicht als
Ersatz für ein normales Telefonnetz.

Aber das schweift nun mächtig vom Thema malloc ab...

von I_ H. (i_h)


Lesenswert?

Und an der Aussage, dass Tokenring ggü Ethernet doch einige Vorteile 
hat, ändert sich auch nix. Es geht ja nicht nur um Latenzen (da hat es 
mal ganz sicher Vorteile), sondern auch um Bandbreite - der Link oben 
erzählt, dass mehr als 40% Brutto_bandbreite_ in einem unswitched 
Ethernet nicht drinnen ist, und so ist es nunmal, denn solange mehrere 
Geräte durcheinanderquatschen werden keine Daten übertragen. Bei 
TokenRing erreicht man praktisch immer volle Bandbreite, auch bei 100 
Rechnern.
Gescheitert ist TokenRing aus ganz anderen Gründen, IBM hatte in der 
Vermarktung noch nie ein gutes Gespür, siehe OS/2. Es gibt übrigens auch 
100mbit TokenRing.


So - fertig mit dem Thema.

von yalu (Gast)


Lesenswert?

Jörg Wunsch schrieb:

> Da du nach eigenen Behauptungen malloc() auf einem Controller noch
> nie benutzt hast, würde ich dir hier einfach mal die Kompetenz
> abstreiten.

Sollte hier statt "Kompetenz" nicht eher "Wagemut" stehen? Bin ich
inkompetent, wenn mich weigere, einen (hypothetischen) Revolver mit
einer Million Kammern, von denen eine einzige geladen ist, an meinem
Kopf abzudrücken, obwohl die Wahrscheinlichkeit, dass ich dabei über'n
Jordan gehe, praktisch vernachlässigbar ist?

> Sicher kannst du einen pathologischen Fall konstruieren, in dem das
> eintreten könnte,

Schon mal was von Herrn Murphy gehört? Der konstruiert gerne solche
Fälle ;-)

> allerdings ist es dann die Frage, wie viel wahrscheinlicher es ist,
> dass deine ganze Controllerapplikation bspw. auf Grund eines
> Hardwarefehlers den Bach vorher runtergegangen ist.

Kannst du denn diese Frage beantworten? Ich nicht.

Kurzum: Es widerstrebt mir eben, bewusst Konstrukte in ein Programm
einzubauen, von denen ich sicher weiß, dass sie nur wahrscheinlich
funktionieren. Vor allem dann, wenn es Alternativen gibt, die diesen
Schönheitsfehler nicht haben.

Aber vielleicht bin ich ja nicht nur inkompetent, sondern auch
paranoid :)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

I_ H. wrote:

> der Link oben
> erzählt, dass mehr als 40% Brutto_bandbreite_ in einem unswitched
> Ethernet nicht drinnen ist, ...

Und genau das ist Humbug.  Ich habe wirklich lange genug mit alten
10-Mbit/s-Ethernets gearbeitet und dort regelmäßig mit > 1 MiB/s
zu tun gehabt -- ob du das nun glaubst oder nicht.  Nein, Switches
hatte es da nicht, das war alles noch RG-58-Verkabelung.

Dass viele PC-Ethernetkarten auf einem ISA-Bus damals diese
Bandbreite nicht geschafft haben, ist ein anderes Thema, aber das
lag nicht am CSMA/CA-Verfahren von Ethernet.

von Peter (Gast)


Lesenswert?

@Jörg Wunsch
> Weil die Anforderung voice nun einmal garantierte Bandbreite braucht,
> und die gibt's ohne QOS einfach nicht

Ich weiss Offtopic g

Leider ist QOS auch keine Lösung, denn was hilft es wenn ein Bandbreite 
von z.b. 1Mbyte/s garantiert wird aber die packete 1sec lang verzögert 
werden? Jitter ist das größte Problem. Und das kann leider auch QOS 
nicht verhindern, dann wenn es einmal ein packet auf die reise schickt 
und es ist sehr gross dann wartet auch das wichtigere Packet erstmal.
QOS ist für Video über Ehternet OK, dann sieht man zwar das bild etwas 
später aber ohne ruckler, aber für VoIP ist Latenz entscheident und das 
kann einem leider niemand in einen "echten" netzt aus vielen Routern und 
Switchs garantieren.

Soweit ich es noch weiss ist das gernerell ein problem von Netzten was 
sich selber organisiert. In Netzten wie Tokenring, ATM, ISDN kann man 
genau die Latenz vorhersagen und das ganze ohne QOS.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

yalu wrote:

> Kurzum: Es widerstrebt mir eben, bewusst Konstrukte in ein Programm
> einzubauen, von denen ich sicher weiß, dass sie nur wahrscheinlich
> funktionieren. Vor allem dann, wenn es Alternativen gibt, die diesen
> Schönheitsfehler nicht haben.

Die sind aber allesamt teurer: du musst Speicher ,,für alle Fälle''
reservieren (und dir trotzdem noch einen Kopf machen, wie du den
Rückzug antrittst, wenn eines Tages ,,mehr als alle Fälle''
gefordert werden).  Wenn du N voneinander unabhängige Ereignisse
hast, must du für alle N Ereignisse jeweils den Maximalplatz
,,für alle Fälle'' reservieren -- nur für den Fall, dass alle N
Ereignisse gleichzeitig auftreten könnten.

Sicherheit war und ist einfach teuer.  Wann immer man Sicherheit
durch eine ausreichende Wahrscheinlichkeit ersetzen kann, kann man
wesentlich billiger werden.  Das ist mehr als eine Frage nach einem
,,Schönheitsfehler''.  Wenn die Wahrscheinlichkeit, dass alle
Ereignisse gleichzeitig auftreten, Größenordnungen geringer ist als
die, dass in deiner Schaltung ein Elko in die Luft fliegt und die
Schaltung sowieso nicht mehr geht, hast du mit der teureren Variante
einfach nur verschwendet.  Das ist sicher OK, wenn davon ein
Menschenleben abhängen kann.  Wenn davon aber nur noch abhängt, ob
ein Funkthermometer einen Messwert in der Anzeige auslässt, dann
wird es sehr viel sinnvoller sein, sich für die preiswertere Variante
zu entscheiden.

(In meinem Falle ist es etwas anders: die malloc-Variante war einfach
überschaubarer zu implementieren und dadurch mit sehr viel weniger
Aufwand bugfrei zu bekommen.  Speicher ist ohnehin genug da, als dass
ich meine nicht vorhandene Perücke darauf verwetten kann, dass der
hier nie ausgehen wird.)

von I_ H. (i_h)


Lesenswert?

Oh mensch... mit 3 Rechnern hab ich auch 1MB/sek geschafft, das machen 
auch ISA Karten (der ISA Bus gibt weit mehr als 1MB/sek her, und wenn du 
nicht die billigste Ethernetkarte nimmst...). Mit 100 Rechnern hast du 
aber, wenn jeder Rechner die Leitung gleich belastet, in einem 10MBit 
unswitched ethernet nur noch 3kb/s pro Rechner (oder noch weniger). Mit 
Tokenring 16MBit sind's dann vll 15kb/s.

Nu überleg mal was besser ist... auf dem Papier steht 10MBit vs. 16MBit, 
in der Praxis ist TR 5mal so schnell.



Btw. GOTO benutze ich auch nicht wirklich, obwohl es stellenweise sehr 
sinnvoll ist.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter wrote:

> Leider ist QOS auch keine Lösung, denn was hilft es wenn ein Bandbreite
> von z.b. 1Mbyte/s garantiert wird aber die packete 1sec lang verzögert
> werden? Jitter ist das größte Problem.

Ja, aber eine ganz andere Baustelle.

Lange Latenzen gibt's auch bei bislang bereits für Telefonie
benutzten Protokollen -- denk nur an Satellitenübertragungen.  Die
sind auf jeden Fall störend, haben aber nichts mit stochastischen
Methoden beim Medienzugriff zu tun (um die es ja anfangs mal ging).

> Soweit ich es noch weiss ist das gernerell ein problem von Netzten was
> sich selber organisiert.

Naja, welches IP-Netz organisiert sich heutzutage kurzfristig selbst?
Langfristig ja, aber kurzfristig (sodass man sich mit Jitter
rumschlagen müsste) ist da bei den Weitstrecken kein Unterschied zu
bspw. ATM.

ATM hat mir vor vielen Jahren mal jemand aus der Szene beschrieben als
,,für IP ungeeignet, weil die Zellen zu klein sind und für Telefonie
ungeeignet, weil die Zellen zu groß sind''. ;-)

von I_ H. (i_h)


Lesenswert?

Lernt doch mal zu unterscheiden zwischen latenzbedingtem 
Bandbreitenverlust, und Bandbreite die durch Kollisionen verloren gehen.

Das eine kann man mit darüberliegenden Techniken vermeiden, das andere 
nur über Switches. Dafür hat man die Dinger erfunden, sind viele NICs an 
einer Leitung steigt die Zahl der Kollisionen irgendwann sprunghaft an, 
und die Bandbreite geht dementsprechend sprunghaft in die Knie.
Das ist nunmal einfach eine Eigenschaft von Ethernet, die Arbitrierung 
ist zwar einfach, aber einfach mal "Hier!" schreien und warten ob 
jemanden unterbrochen wurde ist eben einfach mal nicht effizient.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

I_ H. wrote:

> Oh mensch... mit 3 Rechnern hab ich auch 1MB/sek geschafft, das machen
> auch ISA Karten (der ISA Bus gibt weit mehr als 1MB/sek her, und wenn du
> nicht die billigste Ethernetkarte nimmst...).

Auch mit 10 Rechnern, wenn sie nicht gerade alle gleichzeitig das
Medium mit voller Datenrate belegen wollen.

Klar, den Vorteil, bei voll ausgelastetem Medium die Last gleichmäßig
zu verteilen, habe ich dem TR schon ganz oben eingeräumt.  Allerdings
ist eine 100%ige Auslastung des Mediums auch nicht der Regelfall
(oder zumindest nicht der wünschenswerte Fall).
Sowie die Auslastung unter 90 % runtergeht, hat der TR aber keinen
Vorteil mehr.

Zurück zum malloc: wenn du den Speicher statisch aufteilst, kannst
du vorhersagen, welcher Teil wann in die Röhre guckt und keinen
mehr bekommt.  Da im Normalfall jedoch nicht alle Speicheranforderungen
verschiedener unabhängiger Bedürftiger gleichzeitig erfolgen, ist die
gesamte Speicherauslastung damit schlechter: du reservierst Speicher
für Ereignis B, das im Moment gerade gar nicht anliegt, während
Ereignis A leer ausgeht, da es seine statische Zuweisung erreicht
hat.  Bei dynamischer Vergaben könnte A jetzt trotzdem weiterarbeiten
bis zu dem Punkt, da die Summe aus A und B die Gesamtgrenze erreicht.
(OK, Fragmentierung beim simplen malloc-Prinzip führt zu
vorzeitiger Ressourcenverringerung.  Könnte man durch handle-
basierte Alternativen aber umgehen, bei denen man im Falle der
Ressourcenknappheit eine garbage collection durchführt.)

von I_ H. (i_h)


Lesenswert?

Verstehst du absichtlich nicht, was ich schreibe?

Ethernet 10mbit: 1.25MB/s brutto
TR 16mbit: 2MB/s brutto

Nimm dir ein großes Netz wo alle Rechner irgendwie Daten schaufeln. Ein 
paar regelmäßig wenig (zB. Internetseiten), ein paar etwas mehr. Dann 
schaufeln alle Rechner zusammen bei

Ethernet 10mbit: 30..40% der Bruttorate = 375..500kb/sek, bei
TR 16mbit: 1.8MB/s

Du erreichst bei Ethernet keine 90% Auslastung!!! Bei 30..40% ist 
schluss! Und 30..40% Netzauslastung sind ja wohl schon Regelfall!

Wenn du also ein Netz mit 50 Rechnern machen willst, bei dem insg. 1MB/s 
möglich sein soll, ist 10MBit Ethernet zu langsam! Wie schon gesagt 
sinkt die Bandbreite bei Ethernet sprunghaft, also ab einer bestimmten 
Rechnerzahl nimmt die maximal mögliche Bandbreite rapide ab! (wenn 3/4 
nicht grad ausgeschaltet sind)

von yalu (Gast)


Lesenswert?

Jörg Wunsch schrieb:

> Die sind aber allesamt teurer: du musst Speicher ,,für alle Fälle''
> reservieren (und dir trotzdem noch einen Kopf machen, wie du den
> Rückzug antrittst, wenn eines Tages ,,mehr als alle Fälle''
> gefordert werden).  Wenn du N voneinander unabhängige Ereignisse
> hast, must du für alle N Ereignisse jeweils den Maximalplatz ,,für
> alle Fälle'' reservieren -- nur für den Fall, dass alle N Ereignisse
> gleichzeitig auftreten könnten.

Wenn tatsächlich der Fall eintreten kann, dass alle N Ereignisse
gleichzeitig den Worst-Case an Speicherplatz unbedingt benötigen,
sollte man meiner Meinung nach für diesen Fall gerüstet sein.

Es gibt sicher Fälle, wo man Kompromisse eingehen kann:

Ein klassisches Beispiel sind Büroanwendungen. Die werden halt neu
gestartet, wenn sie gecrasht sind oder eine Speicher-Voll-Meldung
erscheint, da hat sich schon jeder daran gewöhnt.

Ein anderes Beispiel sind Haushaltsgeräte, Messgeräte u.ä., die immer
nur für eine gewisse Zeit in Betrieb sind und bei jedem Einschalten
resettet werden.

Bei einem Gerät, das ständig in Betrieb ist, würde ich diesen
Kompromiss nicht eingehen, egal ob sicherheitskritisch oder nicht. Vor
allem bei fest installierten und schwer zugänglichen Geräten macht es
keinen Spass, sich alle paar Wochen zu einem (möglicherweise aus
Kostengründen nicht einmal existenten) Resetknopf vorzukämpfen, um das
Gerät nach einem Fehlverhalten wieder in einen definierten
Ausgangszustand zu versetzen.

Zur letzten Kategorie zähle ich auch den im Freien installierten
Sensor- und Sendeteil des von dir angesprochenen Funkthermometers,
sofern sich darin ein Mikrocontroller verbirgt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

(Langweilig inzwischen, daher meine letzte Äußerung dazu.)

I_ H. wrote:
> Verstehst du absichtlich nicht, was ich schreibe?
>
> Ethernet 10mbit: 1.25MB/s brutto
> TR 16mbit: 2MB/s brutto

Ja.  Allerdings hättest du hier gegen TR 4 Mbit/s vergleichen müssen,
denn die waren ungefähr zur gleichen Zeit da.

> Du erreichst bei Ethernet keine 90% Auslastung!

Dann bleib bei deinem Glauben.  Ich weiß, dass man die 90 %
Auslastung locker erreicht, ich habe das selbst zu 10-Mbit/s-Zeiten
genügend gehabt.  Und nein, wir hatten nicht nur einen Rechner da
dran, und wir hatte -- wie ich dir ebenfalls schon geschrieben
habe -- keinen Switch, da das alles noch zu Zeiten von 10base2 war.

Im einzigen TR-16-Netz, an dem ich jemals mit dabei war (das dort mehr
aus politischen Gründen noch existierte, es muss wohl mal irgendwann
eine ,,strategische Entscheidung'' der Obrigkeit gewesen sein), war
jeder heilfroh, wenn er zu den privilegierten gehörte, die parallel
dazu noch eine 100-Mbit/s-Ethernetkarte besitzten durfte.  Das war
nämlich ein Unterschied wie Porsche zu VW Käfer.  Dabei war jedoch
aus besagten politischen Gründen die Einführung dieser Netzwerktopologie
dort über Jahre verzögert worden.  Mittlerweile ist auch dort der tote
Ring tot.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

yalu wrote:

> Wenn tatsächlich der Fall eintreten kann, dass alle N Ereignisse
> gleichzeitig den Worst-Case an Speicherplatz unbedingt benötigen,
> sollte man meiner Meinung nach für diesen Fall gerüstet sein.

Dann bist du halt wieder teurer.

Es gibt eine gewisse Wahrscheinlichkeit von > 0, dass die vor dir
liegende Computertastatur plötzlich ,,von allein'' ein paar cm
nach oben springt.  Trotzdem ist das halt so unwahrscheinlich, dass
wir dafür keine Vorkehrungen treffen.  Wir treffen selbst für viel
wahrscheinlichere Ereignisse wie ein Erdbeben keine Vorkehrungen,
weil man zwar erdbebensicher bauen könnte, das aber gemessen an
der geringen Wahrscheinlichkeit billiger ist, die Schäden nach einem
solchen zu reparieren als von vornherein so zu bauen.

> Bei einem Gerät, das ständig in Betrieb ist, würde ich diesen
> Kompromiss nicht eingehen, egal ob sicherheitskritisch oder nicht. Vor
> allem bei fest installierten und schwer zugänglichen Geräten macht es
> keinen Spass, sich alle paar Wochen zu einem (möglicherweise aus
> Kostengründen nicht einmal existenten) Resetknopf vorzukämpfen, um das
> Gerät nach einem Fehlverhalten wieder in einen definierten
> Ausgangszustand zu versetzen.

Das würde ich dann auch unter Fehldesign einsortieren.  Wenn dynamische
Anforderungen auftreten, muss man auch mit dem Zustand der ggf. mal
nicht vorhandenen Ressourcen klar kommen (egal, ob man diese per
statischer Tabelle alloziert hat und Nmax doch zufällig mal über-
schritten wird, oder ob man sich für dynamische Allozierung
entschieden hat).  Damit meine ich nicht, dass man Windowsmäßig es
dem Nutzer zumutet, dann den Resetknopf zu drücken. ;-)  Gerade im
Controllerbereich gibt es ja durchaus andere Möglichkeiten, und sei's
ein ,,Fallrückzieher'' über einen Watchdog-Reset.

von yalu (Gast)


Lesenswert?

> Dann bist du halt wieder teurer.

Das mit den Kosten halte ich für kein gutes Argument. Die sicherere
Variante eines Algorithmus reserviert zwar mehr Platz für Daten, um
alle vorkommenden Fälle abzudecken und benötigt entsprechend viel RAM.

Bei der malloc-Variante belegen die Daten zwar weniger Speicher, weil
die unwahrscheinlichen Fälle, in denen diese Speichermenge nicht
ausreicht, einfach ignoriert werden. Jedoch muss zusätzlicher Speicher
vorgesehen werden

1. für Verwaltungsinformationen )mindestens ein size_t für jeden
   allozierten Speicherblock)

2. für die durch Speicherfragmentierung entstehende, nicht nutzbare
   Lücken

3. etwas Reserve, falls Die Wahrscheinlichkeit des Eintretens des
   unwahrscheinlichen Ereignisses doch größer ist als erwartet

Es hängt sicher von der jeweiligen Anwendung ab, wieviel zusätzliches
RAM diese drei Punkte tatsächlich erfordern, aber ignorieren kann man
sie i.Allg. nicht:

Punkt 1 ist nur dann vernachlässigbar, wenn man nur ganz wenige, sehr
goße Speicherblöcke alloziert. Dafür gibt es aber meist bessere
Methoden als das klassiche malloc.

Punkt 2 ist nur dann vernachlässigbar, wenn alle allozierten
Speicherblöcke die gleiche Größe haben. Auch dafür gibt es wesentlich
bessere Alternativen zu malloc (s. mein erster Beitrag in diesem
Thread). Diese sparen sogar CPU-Zeit und Programmspeicher (wo wir
schon von den Kosten reden ;-)).

Punkt 3 ist nur dann vernachlässigbar, wenn man die Wahrscheinlichkeit
des Versagens der Methode hinreichend genau ermitteln kann und diese
W. kleiner als die W. sonstiger Fehlerursachen, bspw. von
Hardwareausfällen, ist. Das zu entscheiden dürfte aber beliebig schwer
sein.

Deswegen ist malloc ist in meinen Augen ausschließlich dafür geeignet,
die Programmierung zu vereinfachen und damit Entwicklungskosten, nicht
aber Hardwarekosten einzusparen.

Für komplexe PC-Anwendungen, wo aufgrund riesiger RAM-Mengen alle drei
der genannten Punkte kein Thema sind, ist malloc ok, ebenso bei
Mikrocontrolleranwendungen mit geringen Stückzahlen, wo die
Entwicklungskosten wichtiger als die Hardwarekosten sind.

Für weniger komplexe Mikrocontrolleranwendungen mit hohen Stückzahlen
muss sehr genau abgewägt werden, ob man mit malloc tatsächlich
RAM-Bytes sparen kann. Ich würde sagen, in der Mehrheit der Fälle
nicht.

Dadurch, dass die Ausfallswahrscheinlichkeit auf Grund unerwartet
hoher Speicherfragmentierung nur sehr schwer abschätzbar ist, besteht
zusätzlich das Risiko, dass das Produkt bei einer größeren Zahl der
Kunden unzuverlässig arbeitet. Es dürfte klar sein, dass die dann
enstehenden Kosten in einer ganz anderen Größenordnung liegen als die
paar RAM-Bytes, um die wir gerade diskutieren :)

> Gerade im Controllerbereich gibt es ja durchaus andere
> Möglichkeiten, und sei's ein ,,Fallrückzieher'' über einen
> Watchdog-Reset.

Du bist wohl auch so einer, bei dem beim Autofahren in der Kurve
ständig die ESP-Lampe blinkt ;-)

von Simon K. (simon) Benutzerseite


Lesenswert?

yalu wrote:
> Du bist wohl auch so einer, bei dem beim Autofahren in der Kurve
> ständig die ESP-Lampe blinkt ;-)

Aber nur wenn seine ESP Elektronik noch genügend Heap für malloc frei 
hat..

SCNR :D

von I_ H. (i_h)


Lesenswert?

Du bringst da was durcheinander, vll hattet ihr doch ein switched 
ethernet. Auch 10base2 kann man segmentieren.

Überleg mal warum praktisch jedes verdammte Ethernet heute geswitched 
ist, obwohl hubs viel günstiger sind.

Übrigens ist auch GBit Tokenring spezifiziert.

von piepvogel (Gast)


Lesenswert?

noch was zu malloc vs. statischem speicher:
ich persönlich habe nichts gegen malloc, wenn sein einsatz lokal 
begrenzt wird. z.b. hat man auf grösseren µC meistens mehrere 
softwarekomponenten, von denen einige, unkritische wegen 'out of memory' 
auch mal versagen dürfen, während andere unbedingt immer laufen müssen. 
globale nutzung von malloc/free ist ein nicht zu unterschätzendes 
risiko, wenn ein relativ unwichtiges modul plötzlich dafür sorgt, dass 
wichtigen komponenten der speicher fehlt.

von Peter D. (peda)


Lesenswert?

Ich hab ja nichts gegen malloc, bloß ich habs bisher noch nirgends 
gebrauchen können.

Wenn ich irgendwelche lokalen Arrays brauche, dann ist deren Größe schon 
zur Compilezeit bekannt.
Und die Puffer für CAN, I2C, UART usw. müssen ja global sein (es kann ja 
jederzeit was reinkommen / gesendet werden müssen), da nützt malloc auch 
nichts.
Dem Scheduler habe ich die maximale Zahl an gleichzeitigen Prozessen 
auch schon zur Compilezeit reserviert.
Umsortieren muß ich auch nichts.

Ich habe also das Pech, keinerlei sinnvolle Aufgabe für das malloc zu 
haben.


Peter

von A. N. (netbandit)


Lesenswert?

Ich verstehe nicht ganz das Problem. Es ist doch ganz einfach: Kann man 
zur Programmierzeit einschätzen wie viel Speicher benötigt wird (zum 
Beispiel eine Tabelle mit X Einträgen) dann macht man es halt statisch. 
warum sollte man dann malloc benutzen?

Wenn man allerdings zur Programmierzeit nicht weiß wie viel Speicher 
wirklich benutzt wird muss man halt malloc benutzen, das ist doch ganz 
natürlich und absolut sinnvoll. In jedem Fall besser als dann z.B. eine 
Tabelle statisch zu begrenzen. Wenn eben kein Speicher mehr da ist, dann 
muss man diesen Fall halt abfangen und entsprechende Maßnahmen 
ergreifen. Zum Beispiel indem der Benutzer eine Meldung bekommt, er 
solle doch ein paar Einträge aus der Tabelle löschen, wenn er neue 
hinzufügen will. Oder indem weniger wichtige Variablen vielleicht 
kurzfristig auf eine SD Karte oder so ausgelagert werden.

Ich sehe absolut kein Sicherheitsrisiko bei malloc. Man muss halt sauber 
programmieren und den Fehlerfall sinnvoll abfangen und dann kann man 
dank malloc viele Probleme flexibler lösen.

Das einzige Problem mit malloc ist die Sache mit dem Stack, aber auch 
hier kann man ja das Problem lösen, indem man nur einen bestimmten 
Bereich des Speichers für den heap vorsieht.

Aber vielleicht verkenne ich hier ein Problem. eventuell kann mal jemand 
einen hypothetischen Fall erläutern in dem malloc, gegenüber einer 
statischen Speichernutzung schwerwiegende Probleme verursachen kann.

von piepvogel (Gast)


Lesenswert?

> Das einzige Problem mit malloc ist die Sache mit dem Stack, aber auch
> hier kann man ja das Problem lösen, indem man nur einen bestimmten
> Bereich des Speichers für den heap vorsieht.

wieso mit dem stack? und ja, man muss immer einen RAM-bereich für den 
heap reservieren.

> Aber vielleicht verkenne ich hier ein Problem. eventuell kann mal jemand
> einen hypothetischen Fall erläutern in dem malloc, gegenüber einer
> statischen Speichernutzung schwerwiegende Probleme verursachen kann.

softwarekomponenten A und B sind unabhängig, benutzen aber beide 
malloc/free.
A braucht nun temporär sehr viel speicher, jetzt kommt B dran und 
bekommt plötzlich 0 von malloc zurück.

von Simon K. (simon) Benutzerseite


Lesenswert?

piepvogel wrote:
>> Das einzige Problem mit malloc ist die Sache mit dem Stack, aber auch
>> hier kann man ja das Problem lösen, indem man nur einen bestimmten
>> Bereich des Speichers für den heap vorsieht.
>
> wieso mit dem stack? und ja, man muss immer einen RAM-bereich für den
> heap reservieren.

malloc prüft zwar, ob noch genug Platz ist für den Block, der allokiert 
werden soll, ABER der Stack prüft beim Wachsen nicht, ob er in den Heap 
reinläuft. Deswegen kann es da Probleme geben...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

piepvogel wrote:

> wieso mit dem stack? und ja, man muss immer einen RAM-bereich für den
> heap reservieren.

Der Heap wird normalerweise automatisch alloziert.  Übrigens ist
ein Vorteil von malloc() gegenüber alloca() bzw. großen Variablen
auf dem Stack, dass bei RAM-Knappheit malloc() fehlschlägt und
eine 0 zurück gibt, während der Stack sich immer Platz macht --
gegebenenfalls halt in die statischen Variablen hinein.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

I_ H. wrote:

> Du bringst da was durcheinander, vll hattet ihr doch ein switched
> ethernet. Auch 10base2 kann man segmentieren.

Aber Switches gab's da nicht, nur Repeater.  Das einzige Problem, was
diese gelöst haben war, dass ein kaputter Terminator nur einen Strang
lahm gelegt hat, nicht das ganze Netz.  Ansonsten hat man den
kompletten Traffic des gesamten Netzes gesehen -- ich habe tcpdump
oft genug benutzen dürfen zu dieser Zeit...

> Überleg mal warum praktisch jedes verdammte Ethernet heute geswitched
> ist, obwohl hubs viel günstiger sind.

Weil man mit einem hochwertigen Switch halt nochmal ein vielfaches
der Bandbreite des Einzelkabels erreichen kann.  Damit hat man
praktisch eine Konstellation, als hätte man N einzelne Netze jeweils
zwischen den gerade kommunzierienden Maschinen, jede mit voller
Bandbreite.

Weil die Technologie, ein Ethernet zu switchen, seit 100baseTX so
preiswert geworden ist, dass du sie für einen Appel und ein Ei selbst
bei dir zu Hause einsetzen kannst.  (Einen Bandbreitengewinn würde
ich davon aber nicht erwarten.)  Es gibt praktisch keine Hubs mehr.
Der Chinaswitch kostet gerade mal noch so viel, wie die Relais für
einen TR-Port im MAU wohl mal gekostet haben werden.  Die gab's
nämlich auch nicht umsonst, und anders als bei dicken Halbleitern
sinkt deren Preis auch nicht unendlich, wenn man nur genügend davon
anfertigen lässt.

Weil man mit einem managed switch weit mehr machen kann: VLANs,
Ports einzeln konfigurieren (ggf. auch aus der Ferne), Port
security bis hin zu kryptografischer Authentisierung, ...

von I_ H. (i_h)


Lesenswert?

Schonmal dran gedacht, dass man mit einem Rechner ein 10base2 
segmentieren kann? 2 NICs rein, bridge einrichten, fertig. Macht bei 
10base2 in jedem Fall Sinn, eben wegen den Kollisionen.
Dazu braucht man nichtmal einen Rechner, gibt genug Router die sowas 
können, und auch die nötige Hardware on board haben (zB. Cisco).

Also du kannst erzählen was du willst, es ist allgemein bekannt und ich 
hab selber auch schon erlebt, dass man mit 10base2 bzw. unswitched 
ethernet bei weitem nicht die volle Bandbreite erreicht, wenn mehrere 
Rechner dranhängen.
Das ist einer der Hauptgründe wieso Switches eingeführt wurden, die 
billigen haben intern auch nicht viel mehr als 100mbit Bandbreite.

von A. N. (netbandit)


Lesenswert?

piepvogel wrote:
>> Aber vielleicht verkenne ich hier ein Problem. eventuell kann mal jemand
>> einen hypothetischen Fall erläutern in dem malloc, gegenüber einer
>> statischen Speichernutzung schwerwiegende Probleme verursachen kann.
>
> softwarekomponenten A und B sind unabhängig, benutzen aber beide
> malloc/free.
> A braucht nun temporär sehr viel speicher, jetzt kommt B dran und
> bekommt plötzlich 0 von malloc zurück.

Ja aber, das sehe ich halt nicht als Problem, sondern eben gerade als 
Stärke von Malloc, das man hier völlig flexibel darauf reagieren kann. 
Je nach Anwendung gibt man nun den Nutzer eine Meldung, das die Aktion X 
nicht möglich war, da zum Beispiel in der Tabelle Y zu viele Einträge 
sind. der Nutzer kann nun entscheiden ob er die Einträge in der Tabelle 
Y reduziert und dafür X machen kann oder ob er X sein lässt. Falls der 
Prozessor automatisch läuft kann man ja einen teil des speicher 
auslagern oder die unwichtige Anwendung B selbst ein wenig stutzen oder 
A halt nicht ausführen oder warten bis wieder genug speicher frei ist. 
Man ist halt absolut flexibel was die Behandlung des Fehlers angeht und 
je nach Priorität kann man das problem dann so oder so lösen oder die 
Lösung sogar dem Nutzer überlassen... besser gehts doch gar nicht oder?

von Robert (Gast)


Lesenswert?

An die Ethernet-Kampfhähne:

http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-88-4.pdf - seite 14, 
Figure 6 bzw. figure 8.

Gruß
Robert

von I_ H. (i_h)


Lesenswert?

Die Messungen gehen halt leider nur bis 25 Rechner, aber da sieht man 
schon wie sich das entwickelt. Bei großen Paketen steigt die Latenz um 
Faktor >4 vgl. mit 5 Rechnern, und bei kleinen Paketen bleiben noch 
8.5mbit Bandbreite übrig.
Der Effekt der geringeren Bandbreite schaukelt sich mit mehr Rechnern 
immer weiter auf. Denn wenn ein Rechner einmal nicht senden konnte, muss 
er's nochmal versuchen. Bei kleinen Paketen und 1mbit Datenrate werden 
bei 50% Kollisionen glaub effektiv >2mbit belegt. Die neu übertragenen 
Pakete können ja auch wieder Kollisionen auslösen.

Also bei großen Netzen geht das schnell in die Hose. Der erste Link den 
ich gepostet hatte, ging von max. 100 Rechnern aus. Das deckt sich in 
etwa mit dem pdf, da wären bei 100 Rechnern und linearem Verlauf noch 
4mbit übrig. Leider ist es halt nicht linear. Und wie die Latenzen bei 
100 Rechnern aussehen, möcht ich lieber nicht wissen (bei großen Paketen 
sicherlich >1s), und was dann noch von den 4mbit übrig bleibt auch 
nicht.


Ich hab nun endgültig fertig mit dem Thema.

von grrrrrrrrr (Gast)


Lesenswert?

Was soll dieses Netzwerkgeflame in diesem Thread? Ich möchte hier gerne 
was über malloc vs. statische Variablen lesen! Seid ihr denn zum ersten 
mal in einem Forum unterwegs? Hier gibts sowas wie Regeln!

von piepvogel (Gast)


Lesenswert?

>>> Aber vielleicht verkenne ich hier ein Problem. eventuell kann mal jemand
>>> einen hypothetischen Fall erläutern in dem malloc, gegenüber einer
>>> statischen Speichernutzung schwerwiegende Probleme verursachen kann.
>>
>> softwarekomponenten A und B sind unabhängig, benutzen aber beide
>> malloc/free.
>> A braucht nun temporär sehr viel speicher, jetzt kommt B dran und
>> bekommt plötzlich 0 von malloc zurück.

> Ja aber, das sehe ich halt nicht als Problem, sondern eben gerade als
> Stärke von Malloc, das man hier völlig flexibel darauf reagieren kann.
> Je nach Anwendung gibt man nun den Nutzer eine Meldung, das die Aktion X
> nicht möglich war, da zum Beispiel in der Tabelle Y zu viele Einträge
> sind. der Nutzer kann nun entscheiden ob er die Einträge in der Tabelle
> Y reduziert und dafür X machen kann oder ob er X sein lässt. Falls der
> Prozessor automatisch läuft kann man ja einen teil des speicher
> auslagern oder die unwichtige Anwendung B selbst ein wenig stutzen oder
> A halt nicht ausführen oder warten bis wieder genug speicher frei ist.
> Man ist halt absolut flexibel was die Behandlung des Fehlers angeht und
> je nach Priorität kann man das problem dann so oder so lösen oder die
> Lösung sogar dem Nutzer überlassen... besser gehts doch gar nicht oder?

das problem dabei ist, wie gesagt, ein modul dem anderen den speicher 
wegsaugen kann. eine lösung wäre z.b. zwei getrennte heaps zu benutzen.
auch doof sind sogannte heap crashs, also wenn aus irgendeinem grund 
über die 'gemallocte' grenze hinaus geschrieben wurde. in dem fall ist 
der heap kaputt und kein nachfolgendes malloc/free/realloc wird 
zuverlässig arbeiten. alloca() und das C99 feature 'variable length 
arras' sind aber auch gefährlich. verzichtet man auch darauf, können 
einem nur noch rekursive funktionen gefährlich werden. wenns um 
betriebssicherheit geht, geht oft kein weg an statischem speicher 
vorbei. ein compiler kann übrigens zugriffe auf statischen speicher viel 
besser optimieren (noch besser, wenn man das keyword 'restrict' 
verwendet), allein schon, weil keine zusätzlich indirektion erforderlich 
ist, wie bei zugriffen über pointer.

von A. N. (netbandit)


Lesenswert?

piepvogel wrote:

> das problem dabei ist, wie gesagt, ein modul dem anderen den speicher
> wegsaugen kann. eine lösung wäre z.b. zwei getrennte heaps zu benutzen.
Ja, aber wie ich schon oben geschrieben habe, kann man diesen Fehlerfall 
dann abfangen und je nach Situation geeignet darauf reagieren um das 
Programm zu lösen. Daher sehe ich das nicht als ein Nachteil von malloc, 
sondern eben als ein Vorteil, das man auf soetwas flexibel reagieren 
kann.
Oft können ja solche Programmierprobleme nicht statisch gelöst werden da 
ja am Anfang nicht feststeht welches Modul wie benutzt wird und wie viel 
Speicher besetzt. Daher ist es ja gerade schlecht, wenn sich die Module 
statisch den Speicher teilen. Wird da dynamisch, je nach Anforderung 
gemacht kann der Nutzer das System viel besser nach seinen wünschen 
benutzen und stößt nicht so schnell an Grenzen. Stößt er dann doch 
einmal an Grenzen, zum Beispiel im Fall wie du ihn geschildert hast, 
dann muss man das eben programmtechnisch abfangen.
Also das Problem liegt offensichtlich hier nicht bei malloc, sondern 
beim Programmierer der zu faul war das Problem sachgerecht abzufangen.

> auch doof sind sogannte heap crashs, also wenn aus irgendeinem grund
> über die 'gemallocte' grenze hinaus geschrieben wurde. in dem fall ist
> der heap kaputt und kein nachfolgendes malloc/free/realloc wird
> zuverlässig arbeiten.
Das ist aber ein Programmierfehler, wenn so etwas passiert und über eine 
statische Arraygrenze kann man ja auch drüber hinwegschreiben. Soetwas 
darf ja niemals passieren, egal ob statisch oder dynamisch.

> alloca() und das C99 feature 'variable length
> arras' sind aber auch gefährlich. verzichtet man auch darauf, können
> einem nur noch rekursive funktionen gefährlich werden.
Diese Probleme sehe ich als viel unberechenbarer und schlimmer als das 
von dir oben geschilderte Malloc Program. Da man diese Fehler während 
der Laufzeit nicht so günstig abfangen kann, hier schützt nur eine 
absolut saubere Programmierung und ne Menge Platz zwischen Stack und dem 
Rest des Speichers.

> wenns um
> betriebssicherheit geht, geht oft kein weg an statischem speicher
> vorbei.
Wie schon eben beschrieben sehe ich das nicht so. Ganz im Gegenteil. 
Eine saubere dynamische Speicherlösung kann durch ihre Flexibilität 
sogar sicherer sein, da sie im Zweifelsfall für die wirklich wichtigen 
Anwendungen alleine Platz schaffen kann bei einer statischen 
Speicherlösung hingegen sind Möglichkeiten der Fehlerbehandlung beim 
ausgehenden Speicher um ein vielfaches geringer. es ist halt alles nur 
eine Frage der sauberen und verantwortungsbewussten Programmierung.

>ein compiler kann übrigens zugriffe auf statischen speicher viel
> besser optimieren (noch besser, wenn man das keyword 'restrict'
> verwendet), allein schon, weil keine zusätzlich indirektion erforderlich
> ist, wie bei zugriffen über pointer.
Ja das kann ich mir gut vorstellen. Ich gehöre ja selbst auch nicht zu 
den Programmierern die ständig dynamisch Speicher anfordern. Wenn ich 
ein Problem mit statischen Speicher gut lösen kann, dann mache ich das 
auch. Aber es gibt nun einmal Fälle wo man dynamisch einfach besser 
fährt und wo man dank dynamischen Speicher den Mehrwert einer Anwendung 
stark erhöhen kann.

von piepvogel (Gast)


Lesenswert?

>> das problem dabei ist, wie gesagt, ein modul dem anderen den speicher
>> wegsaugen kann. eine lösung wäre z.b. zwei getrennte heaps zu benutzen.
> Ja, aber wie ich schon oben geschrieben habe, kann man diesen Fehlerfall
> dann abfangen und je nach Situation geeignet darauf reagieren um das
> Programm zu lösen. Daher sehe ich das nicht als ein Nachteil von malloc,
> sondern eben als ein Vorteil, das man auf soetwas flexibel reagieren
> kann.
du kannst den fehler aber nur lokal behandeln. mal ein extrembeispiel 
für schlechtes design: während der benutzer eine freundliche nachricht 
sieht, dass er gerade zu viele daten eingegeben hat und sich mal etwas 
zurückhalten soll, musste der netzwerkstack 1000 empfangene pakete 
wegwerfen, weil er keine packetbuffer mehr vom heap bekommt.

>> auch doof sind sogannte heap crashs, also wenn aus irgendeinem grund
>> über die 'gemallocte' grenze hinaus geschrieben wurde. in dem fall ist
>> der heap kaputt und kein nachfolgendes malloc/free/realloc wird
>> zuverlässig arbeiten.
> Das ist aber ein Programmierfehler, wenn so etwas passiert und über eine
> statische Arraygrenze kann man ja auch drüber hinwegschreiben. Soetwas
> darf ja niemals passieren, egal ob statisch oder dynamisch.
in einem projekt von mir steckt eine skriptsprache (compiler und virtual 
machine), in der ein benutzer auch arrays anlegen und rekursionen 
programmieren kann. das ganze verwendet einen separaten heap. der 
benutzer kann durch programmierfehler heap-crashs verursachen. 
runtime-checks bei jedem array-zugriff zu machen, wäre zu langsam. 
trotzdem führt ein heap-crash nicht zu einem absturz des gesamtsystems, 
sondern es wird einfach die skriptausführung abgebrochen und eine 
fehlermeldung erzeugt. das ist der vorteil eines lokalen heaps, der nur 
von einem modul benutzt wird.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.