Laden...

Stack Size erhöhen

Erstellt von Shera vor 11 Jahren Letzter Beitrag vor 11 Jahren 5.564 Views
S
Shera Themenstarter:in
52 Beiträge seit 2011
vor 11 Jahren
Stack Size erhöhen

Hey,

Wir haben ein Problem mit der default-StackSize von C#, welche bei 1 MB liegt.
1 MB reicht nicht.

Wir können zwar die StackSize erhöhen mittels "editbin /stack", aber das ist auf Dauer ja keine lösung 😉

Desweiteren könnten wir Threaden und die StackSize dort erhöhen, aber das hatte bei uns einen sehr komischen Nebeneffekt (Eventuell ausgelöst durch unsafe-Code und Lock und Unlock), daher ist das leider auch keine Lösung.

Wir haben uns nun einige Zeit damit beschäftigt, aber wir haben keine Möglichkeit gefunden. Kennt jemand einen Weg die StackSize definitiv zu erhöhen ?
Ich habe mal unter den Optionen .Net Memory Profiler->Default Session Settings->Real-Time die beiden Werte erhöht, aber ich bin mir nicht sicher, ob das die richtigen Werte sind.

Vielen Dank, Shera

P.S.:
Der Code ist bereits ziemlich optimal, also bitte keine Reden schwingen von wegen "Das hat seinen Sinn mit 1 MB, programmier besser".

6.862 Beiträge seit 2003
vor 11 Jahren

Hallo,

Wenn der Stack nicht reicht, könnt ihr die Methode auch iterativ umformen unter Benutzzung von einem Stack<T> als Datenspeicher, statt dem impliziten Stack.

Baka wa shinanakya naoranai.

Mein XING Profil.

S
Shera Themenstarter:in
52 Beiträge seit 2011
vor 11 Jahren

Iterativ umformen kommt nicht wirklich in Frage 😉

Wir gehen ne 4fach-verkettete Liste mit beliebig größer Ausdehnung durch.
Wäre nicht so einfach, weil das jeweils nächste Element von dem vorherigen abhängt und allen Umgebenden ... Schwer zu erklären 😉

6.862 Beiträge seit 2003
vor 11 Jahren

Man könnte den Stack auch bei der rekursiven Variante einbauen, statt halt alles per Übergabeparameter mitzugeben, benutzt man halt nen Stack als Klassenvariable wo man alles benötigte unterbringt.

PS: Ich würde das nicht mehr Liste nennen, wenn die Elemente so miteinander verknüpft sind - das ist ja dann eher nen Graph von der Topographie her.

Baka wa shinanakya naoranai.

Mein XING Profil.

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo Shera,

auch ich kann in der eigentlichen Frage leider nicht viel beitragen.

Wir können zwar die StackSize erhöhen mittels "editbin /stack", aber das ist auf Dauer ja keine lösung 😉

Warum nicht?

Desweiteren könnten wir Threaden und die StackSize dort erhöhen, aber das hatte bei uns einen sehr komischen Nebeneffekt (Eventuell ausgelöst durch unsafe-Code und Lock und Unlock), daher ist das leider auch keine Lösung.

"lock" klingt danach so, als würden sowieso schon mehrere Threads verwendet. Wenn in diesem Fall die Verlagerung der Ausführung von einem Thread in den anderen zu Synchronisationsfehlern führt, so ist dieser Fehler möglicherweise schon im ursprünglichen Code enthalten und tritt nur nicht oder nur wesentlich seltener zu Tage, wobei dann die Gefahr besteht, dass bei Änderungen in der Umgebung der Fehler doch wieder häufiger oder sogar immer auftritt, Stichwort Racing Condition. Nute die Chance, den Fehler reproduzieren zu können, um ihn ein für alle mal zu beheben.

Wenn dir das gelingt, hast du gleichzeitig eine einfache Lösung für dein eigentliches Problem.

Man könnte den Stack auch bei der rekursiven Variante einbauen, statt halt alles per Übergabeparameter mitzugeben, benutzt man halt nen Stack als Klassenvariable wo man alles benötigte unterbringt.

Da man sich beim iterativen Vorgehen - von Hilfsmethoden abgesehen - die ganze Zeit in demselben Methodenaufruf befindet, reicht normalerweise eine lokale (Stack-)Variable.

Manchmal allerdings ist eine Queue besser geeignet. Der Code, um auf einem Baum oder Graphen mittels einer Schleife und einer Queue eine Breitensuche durchzuführen ist sogar einfacher als die rekursive Variante, die das gleiche tut.

herbivore

S
Shera Themenstarter:in
52 Beiträge seit 2011
vor 11 Jahren

Ja, es handelt sich eher um einen Graph, das stimmt wohl.

Mit EditBin ist zwar sogesehen ok, aber leider kann man nichts debuggen.
Wir haben Editbin als Post-Build-Skript eingebaut, aber das ändert nichts beim Debuggen. Die Stacksize wird nicht erhöht oder zumindest funktioniert es mit dem Debugger leider nicht.

So gesehen hilft das Editbin nicht.

Wir haben ein Bild.
Dieses Bild ist unterteilt in Segmente. In circa 300 * 220 Stück.
Jedes Segment zeigt auf seine 4 Nachbarn. Quasi ein Graph mit Knoten die jeweils 4 Ein- und Ausgänge haben.
Daraus folgt es gibt in etwa 64000 Objekte. Die jeweils 4 Referenzen haben. Also ca. 250000 Referezen.
Kreise in der Rekursion haben wir nicht. Das haben wir ausgeschlossen mittels Booleans, die angeben ob dieses Segment bereits besucht wurde oder nicht.

Ein Array bietet sich nicht an. Für andere Bearbeitungsschritte benötigen wir diese Liste.

Gruß,
Shera

5.658 Beiträge seit 2006
vor 11 Jahren

Iterativ umformen kommt nicht wirklich in Frage 😉

Wieso nicht? Es geht so einfach: Rekursion mit dem Stack<T>-Datentyp

Christian

Weeks of programming can save you hours of planning

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo Shera,

ich will natürlich nicht vereiteln, dass doch noch ein Helfer kommt und sagt, wie du die Stack Size vergrößern kannst (so dass der Debugger weiterhin nutzbar ist). Das wäre sicher die einfachste Lösung.

Anderseits denke ich wie MrSparkle und talla, dass eine Umstellung auf Stack<T> oder Queue<T> nicht so schwierig ist, wie du es vermutest.

Davon abgesehen frage ich mich, warum euch überhaupt der Stack ausgeht. Wie hoch ist denn die maximale Rekursionstiefe? Wenn jeder Knoten des Graphs (innerhalb eines Rekursionspfades) maximal einmal besucht wird, dann kannst sie eigentlich nicht über den genannten 64000 liegen. Und wenn Segmente nur dann besucht werden, wenn sie in irgendeiner Weise ähnlich sind, läge der Wert vermutlich selbst in ungünstigen Fällen sogar noch (wesentlich) niedriger. Aber selbst wenn man mit dem Maximalwert von 64000 rechnet, hätte man bei einem Megabyte Stack Size noch 16Byte pro Funktionsaufruf. Wenn die Methode also nicht allzu viele Parameter hat und an dem rekursiven Zyklus nicht mehrere Methoden beteiligt sind (M1->M2->M3->M1->...), müsstet ihr mit 1MB auskommen.

Ist es für das Funktionieren des Algorithmus wirklich nötig, die volle Rekursionstiefe auszuschöpfen, oder würde er möglicherweise (praktisch) die gleichen Resultate liefern, wenn ihr die Rekursionstiefe künstlich (z.B. auf 1000) begrenzt?

Ich vermute, ihr verwendet momentan Tiefensuche. Wenn tatsächlich nichts von dem bisher gesagten zieht und wenn stattdessen auch Breitensuche verwendet werden kann, nochmal der Vorschlag, bei der Umwandlung in eine iterative Variante eine Queue zu verwenden. Der resultierende Code ist dann wohl sogar einfacher als eine rekursive Tiefensuche.

herbivore

U
1.688 Beiträge seit 2007
vor 11 Jahren

Hallo,

Die Stacksize wird nicht erhöht oder zumindest funktioniert es mit dem Debugger leider nicht.

Möglicherweise, weil der "Visual Studio Hostingprozess" verwendet wird? Versuch mal, diesen in Projekteinstellungen/Debuggen zu deaktivieren.

S
248 Beiträge seit 2008
vor 11 Jahren

Hallo Shera,

ist es möglich für die Berechnung in einem neuen Thread zu machen?
Wenn ja oder dies bereits so ist, kannst du die zu verwendende Stackgröße angeben:
Thread Constructor (ThreadStart, Int32)

Grüße

Hinweis von herbivore vor 11 Jahren

Grundsätzlich sollte es gehen. Warum Shera diese Lösung (noch) nicht verwenden kann, hat er schon im Startbeitrag beschrieben. Allerdings wäre es (sowieso) sinnvoll, die Probleme zu beheben, die diesem Weg entgegen stehen.

S
Shera Themenstarter:in
52 Beiträge seit 2011
vor 11 Jahren

Ja, die Möglichkeit mit dem Thread ist bekannt.
Wir werden es wahrscheinlich auch mit Threading umsetzen.

Wird ein wenig Quellcode-Bearbeitung nach sich ziehen, aber besser als nichts.