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
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...
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...
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.
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
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).
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
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.
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.
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.
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
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)
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.
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.
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
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.
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).
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. ;-)
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.
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))"
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).
@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)
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...
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.
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 :)
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.
@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.
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.)
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.
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''. ;-)
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.
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.)
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)
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.
(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.
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.
> 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 ;-)
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
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.
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.
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
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.
> 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.
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...
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.
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, ...
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.
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?
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
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.
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!
>>> 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.
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.
>> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.