2

我的 C# 应用程序遇到了一些问题。

我确保线程不会访问自身之外的任何资源。

现在我有线程池线程,它建立一个 tcp 连接,创建线程对象并运行,1 个线程的性能非常好。对于 50 个线程,它看起来是一样的,可能慢 5-10%,CPU 10-20%。使用 100 个线程,CPU 使用率从 10-20% 变为 70-99%。

我们的一位开发人员说,与 linux 线程相比,windows 线程很糟糕,上下文切换会招致巨大的损失。他建议使用运行所有实例的 4-8 个核心线程创建多路复用。

但我认为一旦你有 1000 多个线程,这样的问题就会开始发生。任何人都可以评论一些好的资源来阅读更多关于这个主题、线程/cpu 性能和正确做法的信息吗?


编辑:好的许多答案似乎有点离题,因为正在做出一些假设,所以我将添加一些额外的点:

 Running 3 applications with 50 threads at 10-20% cpu usage  makes them all use that much. 30-60% CPU usage total.
 Running 1 application with 150 threads makes it cap cpu at 70-99%.  

这就是我所说的线程不缩放的意思。

4

1 回答 1

8

扩展我的评论..

与 POSIX 线程相比,Windows 线程并不“糟糕”,只是您尝试做的事情超出了 CPU 一次物理处理的能力。CPU 使用率并不是您应该在此处查看的特别相关的性能指标。

如果您的 CPU 有 4 个内核,那么您的最佳持续运行线程数量是 4。如果再多,性能下降就会发生,因为是的,上下文切换会影响性能,因为它试图同时处理线程,只有 1 个资源.

把你的线程想象成你桌子上的一大摞书,你必须把每一本书从每摞的顶部敲下来,你希望它们都尽可能快地完成。你有 4 个这样的书架(线程),但只有 2 个臂(核心),你是怎么做到的?最可能的选择是每次交替使用哪个堆栈来敲书,因此没有真正的性能优势,因为单个堆栈所花费的时间将与其他堆栈一样长。

唯一不同的是,如果您正在运行阻塞(即等待 I/O)操作并且您的线程处于空闲状态。在这段空闲时间内,您的内核可以自由地在另一个线程上工作,这可以带来明显的性能优势。当然,当您的其他线程正在等待的资源变得可用时,您又回到了与当前相同的情况。

于 2013-08-16T13:17:34.000 回答