我的任务是采用现有的单线程蒙特卡罗模拟并对其进行优化。这是 ac# 控制台应用程序,没有 db 访问它从 csv 文件加载数据一次并在最后写出来,所以它几乎只是 CPU 绑定,也只使用大约 50mb 的内存。
我已经通过 Jetbrains dotTrace 分析器运行它。在总执行时间中,大约 30% 用于生成均匀随机数,24% 将均匀随机数转换为正态分布随机数。
基本算法是大量嵌套的 for 循环,以随机数调用和矩阵乘法为中心,每次迭代返回一个双精度数,将其添加到结果列表中,该列表定期排序并测试一些收敛标准(在检查每 5% 的总迭代计数点)如果可以接受,程序会跳出循环并写入结果,否则继续到最后。
我希望开发人员参与进来:
- 我应该使用新的 Thread v ThreadPool
- 我应该看看Microsoft Parallels 扩展库吗
- 我应该看看AForge.Net Parallel.For,http://code.google.com/p/aforge/任何其他库吗?
由于我从未编写过任何并行或多线程代码,因此非常欢迎一些指向上述教程的链接。
- 生成大量正态分布随机数的最佳策略,然后使用这些随机数。应用程序永远不会在此状态下使用统一随机数,它们总是被转换为正态分布,然后被消耗掉。
- 用于随机数生成的良好快速库(并行?)
- 当我采用这种并行方式时的内存考虑,我需要多少额外的东西。
当前应用程序需要 2 小时进行 500,000 次迭代,业务需要将其扩展到 3,000,000 次迭代并每天调用多次,因此需要进行大量优化。
特别想听听使用过Microsoft Parallels Extension或AForge.Net Parallel的人的意见
这需要相当快地进行生产,因此.net 4 beta 已经发布,即使我知道它已经内置了并发库,我们可以考虑在它发布后稍后迁移到 .net 4。目前服务器有.Net 2,我已经提交了我的开发盒有的.net 3.5 SP1 的升级以供审查。
谢谢
更新
我刚刚尝试了 Parallel.For 实现,但它产生了一些奇怪的结果。单线程:
IRandomGenerator rnd = new MersenneTwister();
IDistribution dist = new DiscreteNormalDistribution(discreteNormalDistributionSize);
List<double> results = new List<double>();
for (int i = 0; i < CHECKPOINTS; i++)
{
results.AddRange(Oblist.Simulate(rnd, dist, n));
}
到:
Parallel.For(0, CHECKPOINTS, i =>
{
results.AddRange(Oblist.Simulate(rnd, dist, n));
});
在模拟内部有许多对 rnd.nextUniform() 的调用,我想我得到了许多相同的值,这可能会发生,因为这现在是并行的吗?
也可能是 List AddRange 调用不是线程安全的问题?我看到这个
System.Threading.Collections.BlockingCollection 可能值得使用,但它只有一个 Add 方法,没有 AddRange 所以我必须查看那里的结果并以线程安全的方式添加。非常感谢使用 Parallel.For 的人的任何见解。我暂时切换到System.Random进行调用,因为我在使用 Mersenne Twister 实现调用 nextUniform 时遇到异常,也许它不是线程安全的,某个数组的索引越界......