gpt4 book ai didi

c# - 用于蒙特卡洛的 C# (.Net 4.5) 中的多线程

转载 作者:太空宇宙 更新时间:2023-11-03 21:08:55 24 4
gpt4 key购买 nike

我的任务是采用蒙特卡洛模型并使用多线程使其运行得更快。因为它是蒙特卡罗,每个模拟都独立于下一个。我想手动创建每个线程,因为每个线程都将运行数千次模拟并将每个模拟结果存储在数据库中,我想创建与处理器中的内核一样多的线程,并赋予它们高优先级。

这是用于管理它的核心代码(我正在使用少量模拟进行测试):

        var threads = new List<Thread>();
iNumCores = Environment.ProcessorCount;
iSims = 64;

iNumSimsPerThread = iSims / iNumCores;
for (int iThread = 0; iThread < iNumCores; iThread++)
{
iStart = (iThread * iNumSimsPerThread) + 1;
iEnd = ((iThread + 1) * iNumSimsPerThread);

Thread thread = new Thread(() => ProcessParallelMonteCarloTasks(iStart, iEnd, iSims));
thread.Priority = ThreadPriority.AboveNormal;
thread.Start();
threads.Add(thread);
}
foreach (var thread in threads)
thread.Join();

我的机器有 8 个内核,所以这个测试应该创建 8 个线程,每个线程运行 8 次模拟。当我将结果数据写入数据库时​​,我包括了模拟编号。我希望看到 64 行,每次模拟 1 行。

但是,我每次模拟得到 1 行,最多 40 行,然后在 57 之前有一个间隙,然后 57 到 64 之间的每次模拟有 3 行。

SQL Server results

不幸的是,我无法调试线程,因此不知道发生了什么,也不知道为什么它缺少一些模拟并运行其他模拟的多个副本。当我打开任务管理器时,我可以看到程序运行时有 3-4 个核心未使用。

有什么想法吗?

更新:根据 Andre 的反馈,我查看了线程的调度和“ProcessParallelMonteCarloTasks”函数的执行。

我注意到的第一件事是某些线程在连接到数据库时超时。我将最小池大小更改为等于核心数并解决了该问题,但这是创建线程和运行“ProcessParallelMonteCarloTasks”的顺序:

Execution order

在此实例中,模拟范围“17-24”、“41-48”和“57-64”被调用了两次,而“1-8”、“25-32”和“49-56”丢失了.

更新 2:我一直在观察我的任务管理器,因为它运行并将线程优先级设置为最高。我所看到的表明 3 个线程在 1 个内核上运行,2 个线程在 2 个内核上运行,1 个线程在第四个内核上运行。其他 4 个核心几乎处于闲置状态。有什么方法可以让它每个核心运行 1 个线程?单核运行3个线程开销一定很大。

最佳答案

iStartiEnd 需要是新变量,我现在在你的循环中声明它们,否则(它们是免费的)你最终会捕获使用的变异值。

关于c# - 用于蒙特卡洛的 C# (.Net 4.5) 中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39106922/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com