Drei kleine Fragen

22/04/2009 - 22:44 von Markus Schaber | Report spam

Hallo,

Ich hab drei kleine Fragen zu VS / .NET / C#:

1. Wie kann ich das "generation 0 memory" der CLR vergröàŸern? Ich habe
Geometrieberechnungen (mit NetTopologySuite / NTS), die sehr viele
Temporà¤robjekte erzeugen. Laut Prozess Monitor fà¼hrt das dazu, dass ich
à¼ber 100 Generation 0, ca. 30-50 Generation 1 und noch ca. 5 Generation
2 Garbage Collections pro Sekunde habe. Ich deute das so, dass ein
GroàŸteil der Temporà¤robjekte bis in die Generation 2 "à¼berlebt", bevor
er dann doch abgerà¤umt wird.

Ich vermute, dass fà¼r die 1er und 2er Generation ein globaler Lock
gehalten werden muss, jedenfalls kann ich mir nur so erklà¤ren, dass die
4 Threads auf den 4 CPUs nur insgesamt ca. 50-60% CPU-Last erzeugen.
Lasse ich à¤hnliche Berechnungen in 4 Prozessen mit je 1 Thread laufen,
habe ich 100% CPU-Last. I/O ist praktisch 0, auch kein Swappen (der
Prozess braucht ein paar hundert MB, die Maschine hat Vista64 mit 8
Gig).


2. Wenn ich meine Applikation aus Visual Studio heraus zum Debuggen
starte, wie kann ich dann erreichen, dass mittels System.Diagnostics.
Process.start() gestartete Sub-Prozesse auch automatisch an den
Debugger von Visual Studio "attached" sind? Ich weiàŸ, dass Visual
Studio mit mehreren Prozessen gleichzeitig umgehen kann, da man à¼bers
Kontext-Menu weitere Prozesse starten kann.


3. Ich habe eine Funktion, die zwei Listen vergleicht, und versuche,
eine optimierte Version zu basteln, die genommen wird, wenn die
Listen-Inhalte IEqualtable implementieren. (Siehe Anhang.) Ich habe zwei
Versuche gemacht, der mit "where" fà¼hrt dazu, dass das Programm nicht
compiliert. VS behauptet, es gà¤be bereits eine Funktion mit der
gleichen Signatur, MonoDevelop sagt mir, der Call sei ambigous. Die
zweite Version mit IList<IEquatable<T>> compiliert, dann wird aber
gegen die nicht optimierte Ursprungsversion gelinkt.

Bin ich von C++ Templates verseucht? Wie krieg ich das ans Laufen?


Vielen Dank,
Markus

"A patched buffer overflow doesn't mean that there's one less way
attackers can get into your system; it means that your design process
was so lousy that it permitted buffer overflows, and there are probably
thousands more lurking in your code." - Bruce Schneier



using System;
using System.Collections.Generic;

namespace GenericTemplate {
class MainClass {
public static bool SequenceEquals<T>(IList<T> a, IList<T> b) {
Console.WriteLine("Plain Version");
if (a.Count != b.Count) return false;
for (int i=0; i < a.Count; i+=1) if (Equals(a[i],b[i])==false) return false;
return true;
}

public static bool SequenceEquals<T>(IList<T> a, IList<T> b) where T:IEquatable<T> {
Console.WriteLine("Where version Version");
if (a.Count != b.Count) return false;
for (int i=0; i < a.Count; i+=1) if (a[i].Equals(b[i])==false) return false;
return true;
}

public static bool SequenceEquals<T>(IList<IEquatable<T>> a, List<IList<T>> b) {
Console.WriteLine("List<IEqualtable<T>> Version");
if (a.Count != b.Count) return false;
for (int i=0; i < a.Count; i+=1) if (a[i].Equals(b[i])==false) return false;
return true;
}

public static void Main(string[] args)
{
List<String> sample = new List<String>(new string[]{"hallo","welt"});
Console.WriteLine(SequenceEquals(args, sample));
}
}
}
 

Lesen sie die antworten

#1 Volker Birk
23/04/2009 - 08:40 | Warnen spam
Markus Schaber wrote:
1. Wie kann ich das "generation 0 memory" der CLR vergrößern? Ich habe
Geometrieberechnungen (mit NetTopologySuite / NTS), die sehr viele
Temporàrobjekte erzeugen.



Schabi, geht das nicht, dass Du mehr inplace rechnest? Wenn ich mir die
Beschreibung der GC-Heuristik auf

<http://msdn.microsoft.com/en-us/lib...t.aspx>

anschaue, "tötest" Du mit vielen Objekten sowieso die Performance.

Laut Prozess Monitor führt das dazu, dass ich
über 100 Generation 0, ca. 30-50 Generation 1 und noch ca. 5 Generation
2 Garbage Collections pro Sekunde habe. Ich deute das so, dass ein
Großteil der Temporàrobjekte bis in die Generation 2 "überlebt", bevor
er dann doch abgeràumt wird.



So sieht's aus. Und dabei scheint die Grösse des Generation 0 Memory
nicht das entscheidende Problem zu sein, sondern vielmehr, dass
überhaupt so viele Objekte erzeugt und zerstört werden.

Nochmals: wàre es möglich, dass Du Deine Algorithmen mehr inplace
formulierst? Das ist natürlich unschön in einer Sprache wie Zehraute,
aber es "trickst" den GC natürlich aus.

Ich vermute, dass für die 1er und 2er Generation ein globaler Lock
gehalten werden muss, jedenfalls kann ich mir nur so erklàren, dass die
4 Threads auf den 4 CPUs nur insgesamt ca. 50-60% CPU-Last erzeugen.



Die Implementierung der IL-Runtime wollen wir lieber gar nicht wissen,
oder? Denn wehe, wenn wir's tun:

<http://msdn.microsoft.com/en-us/mag...1.aspx>
| The following paragraphs describe a few of the mechanisms that the
| garbage collector employs when applications have multiple threads:
| Fully Interruptible Code When a collection starts, the collector
| suspends all application threads.

;-)

Lasse ich àhnliche Berechnungen in 4 Prozessen mit je 1 Thread laufen,
habe ich 100% CPU-Last. I/O ist praktisch 0, auch kein Swappen (der
Prozess braucht ein paar hundert MB, die Maschine hat Vista64 mit 8
Gig).



Willkommen in der Welt des Managed Code! Das ist das, was man mit
Management tun muss: austricksen ;-)

2. Wenn ich meine Applikation aus Visual Studio heraus zum Debuggen
starte, wie kann ich dann erreichen, dass mittels System.Diagnostics.
Process.start() gestartete Sub-Prozesse auch automatisch an den
Debugger von Visual Studio "attached" sind?



Nutze dazu am besten die Plugin-Schnittstelle von Visual Studio.
Hier hat sich einer Makros (bisschen unschön) dafür gebastelt:

<http://weblogs.asp.net/pabloretyk/a...s.aspx>

Schöner ist's natürlich, wenn Du eine Startfunktion schreibst, die
gleich nach dem Starten attached - die Synchronisation kriegst Du mit
einem Mutex hin (die sind unter Windows IPC).

3. Ich habe eine Funktion, die zwei Listen vergleicht, und versuche,
eine optimierte Version zu basteln, die genommen wird, wenn die
Listen-Inhalte IEqualtable implementieren. (Siehe Anhang.)



Der Anhang kam hier nicht mit durch.

Ich habe zwei
Versuche gemacht, der mit "where" führt dazu, dass das Programm nicht
compiliert. VS behauptet, es gàbe bereits eine Funktion mit der
gleichen Signatur, MonoDevelop sagt mir, der Call sei ambigous. Die
zweite Version mit IList<IEquatable<T>> compiliert, dann wird aber
gegen die nicht optimierte Ursprungsversion gelinkt.
Bin ich von C++ Templates verseucht? Wie krieg ich das ans Laufen?



Das ist jetzt ein wenig schwierig. Aber Du bist wirklich
Template-verseucht, warum nicht in einem abstrakteren Typ kapseln, der
wirklich ein "if" in der entsprechenden Schnittstellenfunktion hat?

Du hast hier ja sowieso Sprungverteiler, also kannst Du Polymorphie auch
nutzen.

Viele Grüsse,
VB.
Bitte beachten Sie auch die Rückseite dieses Schreibens!

Ähnliche fragen