我在我的代码中使用并行for循环在大量实体(12,000)上运行一个长时间运行的进程。
进程解析一个字符串,经过一些输入文件(我已经读过,考虑到基于IO的东西的数量,线程的好处可能会有问题,但它似乎在其他地方加速了)并输出一个匹配的结果。
最初,这个过程进展得非常快 - 但最终会慢慢爬行。它可能只是打了一些特别棘手的输入数据,但这似乎不太可能看得更近。
在循环中,我添加了一些调试代码,在开始/结束迭代时打印“已启动处理:”和“完成处理:”,然后编写一个程序,将开始和结束配对,最初为了查找哪个ID导致崩溃。
但是,查看不匹配ID的数量,看起来该程序一次处理超过400个不同的实体。这似乎是,由于IO数量众多,它可能是问题的根源。
所以我的问题是(这些):
我意识到这可能是一个有点不正统的问题,如果没有代码可能会很难回答,但是感谢任何帮助,如果您有任何其他信息,请在评论中告诉我。
答案 0 :(得分:2)
如果没有看到某些代码,我可以猜出你问题的答案:
答案 1 :(得分:0)
让我首先确认从硬盘驱动器同时读取2个文件确实是一个非常糟糕的主意(至少直到那里的大多数HD都有SSD),更不用说整个事情使用的数字了。 。 并行性的使用用于使用实际可并发化的资源(CPU功率)来优化处理。如果你从硬盘驱动器中读取了进程读取,那么你将失去大部分好处。
即便如此,即使CPU功率也不容易无限制的并行化。普通的桌面CPU可以同时运行多达10个线程(显然取决于模型,但这是数量级)。
所以有两件事
首先,我假设您的实体使用所有文件,但是您的文件不是太大而无法加载到内存中。如果是这种情况,您应该将文件读入对象(即进入内存),然后使用这些对象对您的实体进行并行处理。如果没有,你基本上依靠硬盘的缓存来在每次需要时不重读你的文件,你的硬盘缓存远远小于你的内存(1000倍)。
第二,你不应该在12.000项目上运行Parallel.For。 Parallel.For实际上(尝试)创建了12.000个线程,这实际上比10个线程更糟糕,因为并列化会产生很大的开销,而且你的CPU根本不能从中受益,因为它不能运行超过10个线程。一次10个线程。
您应该使用更有效的方法,即IEnumerable<T>.AsParallel()
扩展名(随.net 4.0一起提供)。这个将在运行时确定要运行的最佳线程数,然后将可枚举分成多个批次。基本上,它可以为您完成任务 - 但它也会产生很大的开销,所以只有在处理一个元素对CPU来说实际上是昂贵的时候它才有用。
根据我的经验,使用任何并行的东西应始终进行评估,而不是在现实生活中使用它,即通过实际分析您的应用程序。不要以为它会更好地运作。