我想知道你们中间是否有人知道为什么我的表现很糟糕;
我想要实现的目标; 生成220万个文件。要创建每个文件,平均需要2-5个数据库调用。
我正在使用的服务器有24个核心和190GB的RAM。
我将需要生成的文件分成24批。
Whey我使用下面的代码,我的表现很糟糕。生成过程需要一个多小时。
Parrallel.ForEach(batches, batch =>
{
using (var ctx = new MyContext())
{
for each(var file in batch.Files)
{
GenerateFile(file);
}
}
});
但是,当我确保我的程序收到一个参数,以便progam知道要生成哪个批处理,所以我不需要使用并行功能。如果我使用以下.bat文件执行每个批处理的程序;
START CaMaakEiBericht.exe \B1
START CaMaakEiBericht.exe \B2
...
START CaMaakEiBericht.exe \B24
它运行速度惊人!总生成过程不到15分钟! 此批处理文件还确保每个核心的CPU使用率约为90%。当我使用Parallel方法时,我只能获得30-40%的使用率。
有人对此有合理的解释吗?我对这个项目很满意,因为我最终有可能将.NET 4 Parallel库与EF结合使用,但不幸的是,它让我有点失望: - )
我个人有点怀疑EF是这里的瓶颈......当多个进程获取数据时,它是否会在内部缓存一些强加某些锁的内容?
启发我: - )
答案 0 :(得分:4)
我不能说出为什么你的其他EXE文件运行良好,但我可以为你提供的代码提供建议。
您提到您将工作分成24批,然后在批次列表中使用ForEach。通过这种设置,我们的24个核心中的每一个都可以一次处理1个文件。我猜这是你的瓶颈。
如果你愿意的话,每个核心都可以做得更多。尝试这样的事情:
Parallel.ForEach(batches, batch =>
{
Parallel.ForEach(batch.Files, file =>
{
using (var ctx = new MyContext())
{
GenerateFile(file);
}
}
});
或者您可以完全摆脱批次并为其提供完整的文件列表。任务并行库将为您使用多个核心。
Parallel.ForEach(Files, file =>
{
using (var ctx = new MyContext())
{
GenerateFile(file);
}
});
你可能已经知道了这一点,但请记住context is not thread safe,所以你必须在最里面的Parallel.ForEach结构中创建一个新的。