Onl*_*ind 2 c# multithreading processor
我有一台带有8核处理器的计算机,我对我的计算机需要使用8核的最大功能的最大线程数(软件,不是处理器线程)感到怀疑.
我同时创建160个线程,因此我的处理器的每个核心将处理大约20个线程,这是正确的吗?
我的问题是:
我同时创建160个线程,因此我的处理器的每个核心将处理大约20个线程,这是正确的吗?
不完全的.每个核心一次只能处理一个线程.当操作系统决定线程有足够的聚光灯时,它会将其切换为另一个线程.如果你可以在8个线程中完成相同的工作,那么你将获得相同的吞吐量以及避免不必要的上下文切换所带来的节省.
处理器核心的20个线程是一个很好的数字?
没有.每个核心一个线程就是现场.超线程核心数量大约为两个 - 工作效果各不相同.
独立运行的线程数,它将被核心数除以相等数量?
不是.这是由操作系统决定的,在决策过程中往往会采取许多不同的方法.此外,阻塞的线程不会在任何地方执行.实际上,这些线程中的一些线程可能比其他线程占用更多的CPU时间.
如何根据我的处理器知道更多的线程数?
使用比线程更高级别的构造.这意味着将线程池用于简单的工作项,将Parallel.For系列用于"同步"并行化,并将异步Task用于复杂的异步工作任务(包括线程池片段).手动创建线程的原因并不多 - 除非你真的知道自己在做什么,以及为什么在专用线程上使用它很重要.
关键点是这仅适用于CPU工作.您可以轻松地让一个线程同时处理一百个单独的异步任务.在使用await异步API 时,这非常容易使用.每个CPU的单个线程可以轻松地获得100%的利用率,只要它实际上是CPU工作.如果没有,你想要使用异步I/O--在等待时浪费线程(伴随着内存成本,转换开销,超载调度程序,垃圾收集......)没有意义.
典型的例子是处理一些数据库工作的异步Web服务:
string GetUserName(Guid userId)
{
return Db.GetUser(userId).Name;
}
Run Code Online (Sandbox Code Playgroud)
此同步方法将在处理DB请求时占用请求线程.如果您的数据库请求需要一秒钟,并且您同时有2000个请求,则需要2000个线程来处理请求.但是,DB请求只是异步I/O - 该线程基本上等待DB的响应返回.线程浪费了等待.
相反,您可以使用异步API:
async Task<string> GetUserName(Guid userId)
{
var user = await Db.GetUserAsync(userId);
return user.Name;
}
Run Code Online (Sandbox Code Playgroud)
代码几乎完全相同,但await构造实际上并没有阻塞请求线程 - 它基本上说"好了,我已经完成了,你可以使用这个线程做其他事情.当我准备好时,我会ping你回来继续.".这种模式意味着您永远不需要比CPU核心更多的线程 - 如果CPU处于100%,则添加更多线程来处理负载是没有意义的.如果不是,那就意味着某个线程没有做任何CPU工作 - 这很好,它将在另一件工作到来时使用.现在,您有8个线程处理相同的 2000个请求,而不是让2000个线程处理2000个请求.
| 归档时间: |
|
| 查看次数: |
1655 次 |
| 最近记录: |