C#蒙特卡罗增量风险计算优化,随机数,并行执行

时间:2009-07-06 17:20:18

标签: c# multithreading parallel-processing random montecarlo

我目前的任务是优化 Monte Carlo Simulation ,按地区计算一组义务人员的资本充足率数据。

它运行大约10倍太慢,无法生产,需要数量或每日运行。此外,结果数字的粒度需要在某个阶段提升到桌面可能的书本水平,我给出的代码基本上是一个原型,供半生产能力的业务部门使用。

该应用程序目前是单线程的,因此我需要将其设置为多线程,可以查看System.Threading.ThreadPool Microsoft { {3}} 库但我在这家银行的服务器上受限于.NET 2,所以我可能不得不考虑这个人的端口Parallel Extensions

我正在尽力让他们升级到.NET 3.5 SP1,但这对于这样规模的组织来说是一项重要的练习,在我的合同时间范围内可能无法实现。

我使用 http://www.codeproject.com/KB/cs/aforge_parallel.aspx dotTrace)的试用版了解应用。还有哪些好的剖析器?免费的?

许多执行时间花费在生成均匀随机数,然后将其转换为正态分布的随机数。他们正在使用C# http://www.jetbrains.com/profiler 实施。我不确定他们在哪里获得它,或者它是最好的方式来实现这个(或最佳实现)来生成统一的随机数。然后将翻译为正态分布版本以供计算使用(我还没有深入研究过翻译代码)。

使用以下内容的经验是什么?

您知道的任何替代方案?我是C#开发人员,所以更喜欢C#,但 C ++包装应该不是问题,是吗?

甚至可以更快地利用C ++实现。我认为这些库中的一些库将具有最快的方法来直接生成正态分布的随机数,而无需转换步骤。此外,它们可能还有一些其他功能,可以在后续计算中提供帮助。

此款计算机还是四核Opteron 275,8 GB内存,但Windows Server 2003 企业 32位。我应该建议他们升级到 64位操作系统吗?任何支持这一决定的文章的链接都将非常感激。

无论如何,您的任何建议和帮助都非常感谢。

4 个答案:

答案 0 :(得分:4)

我发现Mersenne Twister很快。问题可能在算法(Box-Muller)中将均匀分布转换为高斯分布。标准算法如下:

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

其中x1和x2是均匀随机数,y1和y2是高斯分布输出。

平方根很慢,但是三角形更差,并且它在接近0时不稳定。Taygeta's page在主题上给出了更快的一个(在伪代码中):

         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;

如果他们没有使用这样的东西,你可以通过避免触发功能甚至预先生成随机数来加快速度。

答案 1 :(得分:1)

您是否考虑过指向a profiler at your code?我见过有简单修复的案例得到了非常显着的改进。就像将几个属性切换到字段一样。

答案 2 :(得分:0)

首先要限制使用.Net进行大规模模拟会在前期花费你相当多的性能......但是那说......

如果您正在运行Mersenne Twister的纯C#实现,那么您很可能很难调整所有性能。如果您查看Mersenne Twister reference implementation,您会发现他们的C版本已经针对具有SSE功能的处理器进行了大量优化 - 这非常快。我不相信在C#(或者至少,我不知道如何)中强制使用具有该优化级别的SSE指令是不可能的。我建议围绕Mersenne Twister库编写一个C ++ / CLI包装器(或P / Invoke包装器),看看它会如何影响您的性能。但是,你必须小心托管非托管marhsalling影响你的表现,因为我在这里看到关于这个问题的其他帖子(虽然我现在似乎无法找到它们......)。

我可能会因此而产生一些火焰,但如果性能是您应用程序中的一个重要问题,那么编写良好的C或C ++几乎总是比任何托管或解释语言都更好。

答案 3 :(得分:0)

我的经验是,C#与C ++的相对表现在很大程度上取决于你正在做的事情。这里有一个很好的讨论:

C++ performance vs. Java/C#

对于进行数学的紧密循环(比如矢量物理计算),c ++比C#快2-3倍,尽管perf可能由Sqrt()等基础函数支配。

我采用了混合语言方法,(重新)使用托管C ++ / CLI包装器实现C ++ / OpenMP中最慢的代码。这使您只需“支付使用费用”。

总结了如何使用C ++ / CLI包装本机C / C ++:

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

一旦掌握了C ++ / CLI,就可以轻松运行。