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

Multi-threading in C# (.Net 4.5) for monte-carlo

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

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

        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 个线程,每个线程 运行ning 8 次模拟。当我将结果数据写入数据库时​​,我包括了模拟编号。我希望看到 64 行,每次模拟 1 行。

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

不幸的是,我无法调试线程,因此不知道发生了什么,也不知道为什么它缺少一些模拟和 运行ning 其他人的多个副本。当我打开任务管理器时,我可以看到程序 运行s.

时有 3-4 个核心未使用

有什么想法吗?

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

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

Execution order

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

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

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