繁体   English   中英

.NET中的线程与进程

[英]Threads vs Processes in .NET

我有一个长时间运行的进程,它读取大文件并写入摘要文件。 为了加快速度,我使用常规旧线程同时处理多个文件:

ThreadStart ts = new ThreadStart(Work);
Thread t = new Thread(ts);
t.Start();

我发现即使单独的线程读取单独的文件并且它们之间没有锁定并且在24核盒子上使用4个线程,我甚至无法在CPU上获得10%或在磁盘上获得10%I / O. 如果我在我的应用程序中使用更多线程,它似乎运行得更慢。

我猜我做错了什么,但是好奇的是,如果我第二次和第三次启动整个exe,那么它实际上处理文件的速度提高了两到三倍。 我的问题是,为什么我不能在我的一个应用程序中获得12个线程来处理数据并对机器征税以及3个我的应用实例中的4个线程?

我已经分析了应用程序,最耗时和频繁调用的函数都是字符串处理调用。

您的计算问题可能不受CPU限制,但I / O受限。 说明您的磁盘I / O“仅为10%”并没有帮助。 我不确定这样的性能计数器是否存在。

它在使用更多线程时变慢的原因是因为那些线程都试图同时到达它们各自的文件,而磁盘子系统很难试图容纳所有不同的线程。 你看,即使采用像SSD这样的现代技术,寻道时间比传统硬盘小几个数量级,仍然会受到惩罚。

相反,您应该得出结论,您的问题是磁盘绑定的,单个线程可能是解决问题的最快方法。

有人可能会争辩说你可以使用异步技术来处理已被读取的位,而在后台读取下一位,但我认为你会看到很少的性能提升。

我不久前在一个小工具中遇到了类似的问题,我想计算硬盘上所有文件的MD5签名,我发现CPU与存储系统相比速度太快,我尝试了类似的结果通过使用更多线程获得更多性能。

使用任务并行库并没有缓解这个问题。

首先在一个24核盒子上,如果你只使用4个线程,它可以使用的最大cpu是16.7%,所以你的利用率实际上是60%,这是相当不错的。

很难说你的程序在这一点上是否受I / O约束,我的猜测是。 您需要在项目中运行探查器,并查看项目花费大部分时间的代码段。 如果它正在进行读/写操作,则它是I / O绑定的。

你可能会使用某种形式的线程间锁定。 这会导致程序在添加更多线程时变慢,是运行第二个进程会解决这个问题,但修复锁定也会。

这一切归结为没有分析信息我们不能说如果使用第二个进程会加快速度或减慢速度,我们需要知道程序是挂在I / O操作,锁定操作还是只是在可以更好地并行化的功能中花费很长时间。

我想你会发现当一个进程同时在多个文件中写入数据时,哪个文件缓存不理想。 当脏页面缓存的数量超过阈值时,文件缓存应同步到磁盘。 似乎一个进程中的并发编写器比单线程编写器更快地达到阈值。 您可以在此处阅读有关文件系统缓存的文件缓存性能和调优

尝试使用.net 4中的任务库(System.Threading.Task)。 该库具有针对不同数量的处理器的内置优化。

不知道你的问题是什么,也许是因为你的代码片段并不真正提供信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM