Domanda

Il mio compito attuale è quello di ottimizzare una simulazione Monte Carlo che calcola figure Capital adeguatezza regione per un insieme di Obligors.

E 'in esecuzione di circa 10 x troppo lento per cui si dovrà essere in produzione e il numero o corse giornaliere necessarie. Inoltre la granularità delle figure di risultato dovrà essere migliorata fino al banco possibilmente livello di libro a un certo punto, il codice mi è stata data è fondamentalmente un prototipo che viene utilizzato da unità di business in una capacità di produzione di semi.

L'applicazione è attualmente single threaded in modo avrò bisogno per rendere più multi-threaded , può guardare System.Threading.ThreadPool o Microsoft estensioni Parallel biblioteca ma sto costretto a .NET 2 sul server in questa banca così io possa avere di prendere in considerazione la porta di questo ragazzo, http://www.codeproject.com/KB/cs/aforge_parallel aspx .

Sto cercando mio meglio per farli passare a .NET 3.5 SP1, ma è un grande esercizio di un'organizzazione di queste dimensioni e potrebbe non essere possibile nel mio contratto time frame.

Ho fatto il profilo dell'applicazione utilizzando il processo di dotTrace ( http://www.jetbrains.com/profiler ). Che esistono altri buoni profiler? quelli gratuiti?

Molto del tempo di esecuzione è trascorso generazione di numeri casuali uniformi e poi tradurre a un numero casuale distribuzione normale. Stanno usando un C # Mersenne Twister implementazione. Non sono sicuro dove hanno preso o se è il modo migliore per andare su questo (o migliore implementazione) per generare i numeri casuali uniformi. Allora questo è tradotto in una distribuzione normale versione per l'utilizzo nel calcolo (non ho approfondito il codice di traduzione ancora).

Anche ciò che è l'esperienza utilizzando la seguente?

Le eventuali alternative conoscete? Sono uno sviluppatore C # in modo preferirebbe C #, ma un wrapper per C ++ non dovrebbe essere un problema, dovrebbe?

Forse ancora più velocemente sfruttando le implementazioni C ++. Sto pensando alcune di queste librerie avrà il metodo più veloce per generare direttamente numeri casuali normalmente distribuite, senza il passaggio di traduzione. Inoltre essi possono avere alcune altre funzioni che saranno utili nei calcoli successivi.

Anche il computer è su un Quad Core Opteron 275, 8 GB di memoria, ma Windows Server 2003 Enterprise 32 bit . Dovrei consigliare loro di passare a un 64 bit OS ? Tutti i link ad articoli che sostengono questa decisione sarebbe davvero apprezzato.

In ogni caso, tutti i consigli e aiuto si può avere è molto apprezzato.

È stato utile?

Soluzione

Ho trovato il Mersenne Twister per essere veloce. Il problema potrebbe essere nell'algoritmo (Box-Muller) per trasformare la distrubuzione uniforme distribuzione gaussiana. L'algoritmo standard appare come:

y1 = sqrt( - 2 ln(x1) ) cos( 2 pi x2 )
y2 = sqrt( - 2 ln(x1) ) sin( 2 pi x2 )

Dove x1 e x2 sono numeri casuali uniformi e y1 e y2 sono le uscite distribuzione gaussiana.

Le radici quadrate sono lenti, ma il trig è peggio, ed è instabile vicino a 0. la pagina di Taygeta sull'argomento dà uno più veloce (in pseudocodice):

         float x1, x2, w, y1, y2;

     do {
             x1 = 2.0 * ranf() - 1.0;
             x2 = 2.0 * ranf() - 1.0;
             w = x1 * x1 + x2 * x2;
     } while ( w >= 1.0 );

     w = sqrt( (-2.0 * ln( w ) ) / w );
     y1 = x1 * w;
     y2 = x2 * w;

Se non stai usando qualcosa di simile, si può essere in grado di accelerare le cose un po ', evitando le funzioni trigonometriche o anche pre-generano i numeri casuali.

Altri suggerimenti

Avete preso in considerazione di puntamento un profiler al tuo codice ? Ho visto casi in cui vi siano semplici correzioni ottenere miglioramenti molto significativi. Come passare un paio di proprietà verso i campi.

Essere costretti a utilizzare .Net, in primo luogo per una simulazione su larga scala sta andando a costare un po 'di prestazioni proprio davanti ... ma che ha detto ...

Se si sta eseguendo una pura implementazione C # del Mersenne Twister, è probabile che avrete un momento difficile tweaking tutte le prestazioni è possibile fuori di esso. Se si estrae il Mersenne Twister implementazione di riferimento vedrete hanno una versione C che è fortemente ottimizzato per i processori SSE-capable - questo è molto veloce. Non credo che sia possibile in C # (o almeno, io non sono a conoscenza di come) per forzare l'uso di istruzioni SSE con quel livello di ottimizzazione. Io suggerirei a scrivere un wrapper C ++ / CLI (o un P / Invoke involucro) attorno alle librerie Mersenne Twister, e vedere come questo influenzi le prestazioni. Tuttavia, dovrete stare attenti con gestito gestito marhsalling influenzare le prestazioni, come ho visto altri post qui su SO su questo problema (anche se non riesco a trovare loro in questo momento ...).

io possa generare qualche fiamma per dire questo, ma se le prestazioni sono un problema significativo nell'applicazione, C o C ++ ben scritto è quasi sempre sarà preferibile a qualsiasi linguaggio gestito o interpretate.

La mia esperienza è che la performance relativa di C # con la C ++ è in gran parte dipende da quello che stai facendo. Una grande discussione di quella qui:

C ++ prestazioni contro Java / C #

Per cicli stretti facendo matematica (dire calcoli di fisica vettoriale) C ++ è un 2-3 volte più veloce di C #, anche se il perf può essere dominata dalle funzioni di base come sqrt ().

Ho preso un approccio lingua mista, (ri) attuare il codice più lento in C ++ / OpenMP con un involucro gestita C ++ / CLI. Ciò consente di solo "paga per quello che si utilizza".

C'è una sintesi di come avvolgere nativo C / C ++ con C ++ / CLI qui:

http://msdn.microsoft.com/en-us/library /ms235281.aspx

Una volta a ottenere il blocco di C ++ / CLI è abbastanza facile per ottenere le cose in esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top