C # Monte Carlo Incremental Risk Berechnungsoptimierung, Zufallszahlen, parallele Ausführung

8

Meine derzeitige Aufgabe besteht darin, eine Monte-Carlo-Simulation zu optimieren, die Kapitaladäquanzzahlen berechnet Region für eine Reihe von Schuldnern.

Es läuft ungefähr 10 x zu langsam für wo es in der Produktion sein muss und Anzahl oder tägliche Läufe erforderlich sind. Darüber hinaus muss die Granularität der Ergebniszahlen bis auf den Schreibtisch, möglicherweise auf Buchebene, verbessert werden. Der Code, den ich erhalten habe, ist im Grunde ein Prototyp, der von Geschäftseinheiten in einer Semi-Produktionskapazität verwendet wird.

Die Anwendung ist momentan single-threaded , daher muss ich multi-threaded machen, vielleicht in System.Threading.ThreadPool oder in Microsoft Parallel Erweiterungen Bibliothek, aber ich bin auf .NET 2 auf dem Server bei dieser Bank beschränkt, so muss ich vielleicht darüber nachdenken Typ Port, Ссылка .

Ich versuche mein Bestes, um sie dazu zu bringen, auf .NET 3.5 SP1 zu aktualisieren, aber es ist eine große Übung in einer Organisation dieser Größe und möglicherweise nicht in meinen Vertragszeitrahmen möglich.

Ich habe die Anwendung mithilfe der Testversion von dotTrace ( Ссылка ). Welche anderen guten Profiler gibt es? Freie?

Ein Großteil der Ausführungszeit wird ausgegeben, indem einheitliche Zufallszahlen erzeugt werden und dann in eine normalverteilte Zufallszahl übersetzt wird. Sie verwenden eine C # Mersenne twister Implementierung. Ich bin mir nicht sicher, wo sie es hinbekommen haben oder ob es der beste Weg ist, um diese (oder die beste Implementierung) zu erreichen, um die einheitlichen Zufallszahlen zu erzeugen. Dann wird für die Berechnung in eine normalverteilte Version übersetzt (ich habe mich noch nicht in den Übersetzungscode vertieft).

Was ist die Erfahrung mit den folgenden?

Irgendwelche Alternativen, die Sie kennen? Ich bin ein C # -Entwickler und würde C # bevorzugen, aber ein Wrapper für C ++ sollte kein Problem sein, oder?

Vielleicht noch schneller die C ++ - Implementierungen nutzen. Ich denke, einige dieser Bibliotheken haben die schnellste Methode, um normal verteilte Zufallszahlen ohne den Übersetzungsschritt direkt zu erzeugen. Sie können auch einige andere Funktionen haben, die in den nachfolgenden Berechnungen hilfreich sein werden.

Auch der Computer ist ein Quad-Core-Opteron 275, 8 GB Speicher aber Windows Server 2003 Enterprise 32 Bit . Sollte ich ihnen raten, auf ein 64 bit OS zu aktualisieren? Alle Links zu Artikeln, die diese Entscheidung unterstützen, würden wirklich geschätzt.

Wie auch immer, jeder Rat und jede Hilfe, die Sie vielleicht haben, wird wirklich geschätzt.

    
m3ntat 06.07.2009, 17:20
quelle

4 Antworten

4

Ich habe festgestellt, dass der Mersenne Twister schnell ist. Das Problem könnte im Algorithmus (Box-Muller) liegen, um die gleichmäßige Verteilung in Gaußsche Verteilung zu transformieren. Der Standardalgorithmus sieht folgendermaßen aus:

%Vor%

Wobei x1 und x2 gleichartige Zufallszahlen sind und y1 und y2 die Gaußschen Verteilungsausgaben sind.

Die Quadratwurzeln sind langsam, aber die Triggerung ist schlimmer, und sie ist nahe bei 0 instabil. Taygetas Seite zum Thema gibt es einen schnelleren (im Pseudocode):

%Vor%

Wenn sie so etwas nicht verwenden, können Sie vielleicht etwas beschleunigen, indem Sie die Triggerfunktionen vermeiden oder sogar die Zufallszahlen vorgenerieren.

    
R Ubben 06.07.2009, 17:57
quelle
1

Haben Sie daran gedacht, einen Profiler auf Ihren Code zu setzen ? Ich habe Fälle gesehen, in denen einfache Korrekturen sehr deutliche Verbesserungen bringen. Wie ein paar Eigenschaften zu Feldern wechseln.

    
Jake Pearson 06.07.2009 17:23
quelle
0

Wenn Sie gezwungen sind, .Net in erster Linie für eine groß angelegte Simulation zu verwenden, kostet Sie das ziemlich viel Leistung ... aber das sagte ...

Wenn Sie eine reine C # -Implementierung des Mersenne Twisters verwenden, ist es wahrscheinlich schwierig, die gesamte Leistung zu optimieren. Wenn Sie sich die Mersenne Twister Referenzimplementierung ansehen ' Ich sehe, sie haben eine C-Version, die stark für SSE-fähige Prozessoren optimiert ist - das ist sehr schnell. Ich glaube nicht, dass es in C # möglich ist (oder zumindest weiß ich nicht, wie), die Verwendung von SSE-Anweisungen mit dieser Optimierungsebene zu erzwingen. Ich würde vorschlagen, einen C ++ / CLI-Wrapper (oder einen P / Invoke-Wrapper) um die Mersenne Twister-Bibliotheken zu schreiben und zu sehen, wie sich das auf Ihre Leistung auswirkt. Allerdings müssen Sie vorsichtig mit Managed-unmanaged Marshsalling sein, was sich auf Ihre Performance auswirkt, da ich hier in SO weitere Beiträge zu diesem Problem gesehen habe (obwohl ich sie momentan anscheinend nicht finden kann ...).

>

Ich kann etwas Flamme erzeugen, um dies zu sagen, aber wenn die Leistung in Ihrer Anwendung von Bedeutung ist, ist gut geschriebenes C oder C ++ fast immer besser als jede verwaltete oder interpretierte Sprache.

    
Not Sure 06.07.2009 17:43
quelle
0

Nach meiner Erfahrung hängt die relative Leistung von C # vs. C ++ stark davon ab, was Sie tun. Eine großartige Diskussion darüber:

C ++ - Leistung vs. Java / C #

Für enge Schleifen, die Mathe ausführen (sagen wir Vektorphysik-Berechnungen), ist c ++ 2-3 mal schneller als C #, obwohl die Perf-Funktion durch die zugrunde liegenden Funktionen wie Sqrt () dominiert sein kann.

Ich habe einen gemischten Ansatz gewählt, indem ich den langsamsten Code in C ++ / OpenMP mit einem verwalteten C ++ / CLI-Wrapper (wieder) implementiere. Dadurch können Sie nur für das bezahlen, was Sie verwenden.

Es gibt eine Zusammenfassung, wie man natives C / C ++ mit C ++ / CLI umschließt:

Ссылка

Sobald Sie mit C ++ / CLI fertig sind, ist es ziemlich einfach, Dinge zum Laufen zu bringen.

    
Ade Miller 08.07.2009 21:34
quelle