Mar*_*tin 13 .net c# multithreading asynchronous
我有一个CPU密集型的应用程序.在单个线程上处理数据时,CPU使用率会持续很长时间达到100%.因此应用程序的性能似乎受到CPU的约束.我已经多线程化了应用程序的逻辑,从而提高了整体性能.但是,CPU使用率几乎不超过30%-50%.我期望CPU(和许多核心)达到100%,因为我同时处理了许多数据集.
下面是我用来启动线程的逻辑的简化示例.当我运行这个例子时,CPU达到100%(在8/16核心机器上).但是,我使用相同模式的应用程序没有.
public class DataExecutionContext
{
public int Counter { get; set; }
// Arrays of data
}
static void Main(string[] args)
{
// Load data from the database into the context
var contexts = new List<DataExecutionContext>(100);
for (int i = 0; i < 100; i++)
{
contexts.Add(new DataExecutionContext());
}
// Data loaded. Start to process.
var latch = new CountdownEvent(contexts.Count);
var processData = new Action<DataExecutionContext>(c =>
{
// The thread doesn't access data from a DB, file,
// network, etc. It reads and write data in RAM only
// (in its context).
for (int i = 0; i < 100000000; i++)
c.Counter++;
});
foreach (var context in contexts)
{
processData.BeginInvoke(context, new AsyncCallback(ar =>
{
latch.Signal();
}), null);
}
latch.Wait();
}
Run Code Online (Sandbox Code Playgroud)
我已将锁的数量减少到严格的最小值(只有锁定器锁定).我发现的最好方法是创建一个线程可以在内存中读/写的上下文.上下文不在其他线程之间共享.线程无法访问数据库,文件或网络.换句话说,我描述了我的应用程序,我没有发现任何瓶颈.
为什么我的应用程序的CPU使用率不会达到50%左右?这是我使用的模式吗?我应该创建自己的线程而不是使用.Net线程池吗?有没有陷阱?有什么工具可以推荐我找到我的问题吗?
谢谢!
有很多事情可能会导致这种行为.
首先,你有什么类型的CPU?如果您有一个i7或类似的处理器,操作系统会将其视为具有8个内核,而实际上,它有4个内核和2个超线程/核心.对于大多数操作而言,即使操作系统以这种方式看待,超线程也不能提供与第二个核心相同的可扩展性.我有这个原因导致我的整体CPU使用率低于操作系统......
其次,你可能会发生某种形式的真正共享.你提到你有锁定 - 即使它被保持在最低限度,锁可能会阻止你有效地安排这个.
此外,您现在正在安排所有100个工作项目.操作系统必须进出这100个线程.您可能希望将此限制为仅允许在给定时间处理特定数字.使用新的任务并行库(使用Parallel.ForEach并使用ParallelOptions设置来获得最大线程数)会更容易 - 但可以自己完成.
鉴于您要安排所有100个项目同时处理,分页可能会妨碍获得最大吞吐量的能力.
此外,如果您正在进行任何其他"更真实"的工作 - 您可能会遇到错误的共享问题,尤其是在您使用共享的数组或集合时(即使您处理的元素未共享).
我建议在VS 2010中的并发分析器下运行它 - 它会让你更清楚地了解正在发生的事情.