我正在开发一个应用程序,它可以扫描数千个结构副本; ~1 GB 内存。速度很重要。
ParallelScan(_from, _to); //In a new thread
我手动调整线程数:
if (myStructs.Count == 0) { threads = 0; }
else if (myStructs.Count < 1 * Number.Thousand) { threads = 1; }
else if (myStructs.Count < 3 * Number.Thousand) { threads = 2; }
else if (myStructs.Count < 5 * Number.Thousand) { threads = 4; }
else if (myStructs.Count < 10 * Number.Thousand) { threads = 8; }
else if (myStructs.Count < 20 * Number.Thousand) { threads = 12; }
else if (myStructs.Count < 30 * Number.Thousand) { threads = 20; }
else if (myStructs.Count < 50 * Number.Thousand) { threads = 30; }
else threads = 40;
我只是从头开始写它,我需要为另一个 CPU 等修改它。我想我可以写一个更聪明的代码,如果 CPU 可用,它会动态启动一个新线程:
- 如果CPU不是%100启动N个线程
- 测量 CPU 或线程处理时间并修改/估计 N
- 循环直到扫描所有结构体数组
有没有人认为“我做了类似的事情”或“我有更好的主意”?
更新:解决方案
Parallel.For(0, myStructs.Count - 1, (x) =>
{
ParallelScan(x, x); // Will be ParallelScan(x);
});
我确实修剪了大量代码。谢谢大家!
更新 2:结果
10K 模板的扫描时间
- 1 个线程:500 毫秒
- 10 个线程:300 毫秒
- 40 个线程:600 毫秒
- 任务:100 毫秒
最佳答案
标准答案:使用任务 (TPL),而不是线程。任务需要 Fx4。
您的 ParallelScan 可以只使用 Parallel.Foreach( ... )
或 PLINQ (.AsParallel()
)。
TPL 框架包括一个调度器,ForEach()
使用分区器,以适应 CPU 内核和负载。您的问题很可能通过标准组件得到解决,但您可以编写自定义调度程序和分区程序。
关于c# - 运行最大线程 : Automatic performance adjustment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6911228/