我有一些学生,我正在帮助他们使用流媒体服务器。他们使用同步套接字和每个客户端一个线程,这不是非常有效。最好使用异步方法让.Net使用IOCP。
问题是我没有花时间考虑异步套接字何时变得比一个线程/套接字类型的体系结构更有效。 IIRC它最高效的两个每个核心有两个线程?
有人可以解释一下吗?什么时候异步套接字变得更有效?每个核心的最佳线程数是多少?
答案 0 :(得分:2)
异步套接字总是更有效率。
同步和异步套接字之间的区别在于异步套接字使用I/O completion ports而不是阻塞线程。与没有线程相比,被阻塞的线程会消耗额外的资源,主要是内存。
关于每个核心的线程数量的讨论是错误的 最有效的线程数是每个核心执行一个线程。不多也不少。在使用同步解决方案的情况下,线程将在等待数据时被阻止(因此不会在CPU上执行)。在异步解决方案中,在等待数据时CPU上也不会执行任何线程(但是线程阻塞的次数会减少)。在这两种情况下,执行线程的数量都是相同的,但异步将使用更少的内存开销。
修改强>
关于每个核心只有一个执行线程的一些注释
更多线程将为您提供上下文切换开销,而更少的线程会使某些内核空闲
但是,当涉及I / O时,实际上达到理想的线程数是一项艰巨的任务,因为线程并不是一直处于忙碌状态。因此,如果线程被阻塞等待I / O,则可以拥有比核心更多的线程,但是您应该尝试平衡线程的过度配置,以便每个核心实际上始终执行一个接近一个线程。
编辑2:
再说一遍。不要担心像一个或两个客户端这样的低负载期间的效率(除非是实际用户数),优化最高可能负载,即性能重要时。
答案 1 :(得分:1)
这取决于应用程序。如果有1000个线程在等待磁盘或网络I / O或10个线程在进行计算... 无论如何,事件驱动的设计更有效率,每个CPU没有线程和进程(如果有超线程,则为虚拟CPU)。 观察您的应用程序的行为方式并相应地调整线程数。
答案 2 :(得分:1)
标准“每个核心一个线程”不适用于此处。该线程大量等待连接速度慢和I / O完成。由于涉及套接字的线程通常很少做任何实际工作,因此使用异步套接字很快就会成为一种胜利。
如果异步完成处理程序本身正在大量等待I / O(可能是磁盘或dbase),这会发生变化,线程池调度程序可能需要一段时间来赶上尚未完成但尚未完成的工作程序燃烧周期。额外的TP线程每秒只添加两次。