要设定一个速度的提高所导致的任何形式的多计算,你必须假定,要么多基于CPU的任务正在于多个计算资源(通常是处理器核心)并行执行,否则,不是所有的的任务依赖于同一资源的并发使用 - 也就是说,一些任务可能依赖于一个系统子组件(比如磁盘存储),而一些任务依赖于另一个(接收来自外围设备的通信),还有一些任务可能需要处理器内核的使用。
第一种情况通常被称为“并行”编程。第二种情况通常被称为“并发”或“异步”编程,尽管“并发”有时也用于指代仅允许操作系统交错执行多个任务的情况,而不管这种执行是否需要串行放置或者如果可以使用多个资源来实现并行执行。在后一种情况下,“并发”一般是指执行被写入程序的方式,而不是从任务执行的实际同时性的角度来看。
用默认的假设来谈论所有这一切很容易。例如,有些人可以很快做出诸如“异步I/O比多线程I/O更快”的说法。这个说法有几个原因是可疑的。首先,可能会出现这样的情况:某些给定的异步I/O框架可以精确地使用多线程来实现,在这种情况下它们是相同的,并且说一个概念“比另一个更快”是没有意义的。第二,即使在有异步框架(如单线程事件循环)的单线程实现的情况下,您仍然必须假定该循环正在做什么。例如,您可以使用单线程事件循环做的一件愚蠢的事情是请求它异步完成两个不同的纯粹CPU限制的任务。如果你只在一台只有理想化单处理器内核的机器上进行(忽略现代硬件优化),那么“异步”执行这个任务不会有任何不同,而不是用两个独立管理的线程执行任务,或者只用一个独立的进程执行 - - 这种差异可能归结为线程切换或操作系统进度优化,但是如果两种任务都转到CPU,那么在任何情况下都是相似的。
想象你会遇到很多不寻常或愚蠢的角落案例是很有用的。
“异步”并非必须是并发的,例如,如上所述:“异步”在具有一个处理器内核的计算机上执行两个CPU限制任务。多线程执行并不一定是并发的:在一个处理器核心的机器上产生两个线程,或者要求两个线程获取任何其他类型的稀缺资源(想象一下,一个网络数据库一次只能建立一个连接)。线程的执行可能是交错然而,操作系统调度程序看起来合适,但它们的总运行时间不能在单个内核上减少(并且将从线程上下文切换中增加)(或者更一般地,如果产生的线程多于有核心来运行它们,或者有更多的线程要求资源而不是资源能够维持的资源)。同样的事情也适用于多处理。
因此,就运行时而言,异步I/O和多线程都不能提供任何性能增益。他们甚至可以放慢速度。
但是,如果您定义了一个特定的用例,就像一个特定的程序一样,这个程序既可以通过网络调用来从网络连接的资源(如远程数据库)检索数据,也可以执行一些本地CPU计算,在给出关于硬件的特定假设的情况下开始推断两种方法之间的性能差异。
问题要问:我需要执行多少个计算步骤以及需要执行多少个独立系统资源?是否有需要使用独立系统子组件的计算步骤的子集,并且可以同时获得这些子组件的好处?我拥有多少个处理器核心?使用多个处理器或线程在不同核心上完成任务的开销是多少?
如果您的任务很大程度上依赖于独立的子系统,那么异步解决方案可能会很好。如果处理它所需的线程数量很大,以至于操作系统的上下文切换变得不平凡,那么单线程异步解决方案可能会更好。当任务被同一资源绑定(例如多个需要同时访问同一个网络或本地资源)时,那么多线程可能会引入不令人满意的开销,并且尽管单线程异步可能会导致较少的开销在这种资源有限的情况下,它也不能产生加速。在这种情况下,唯一的选择(如果你想加快速度)就是使该资源的多个副本可用(例如,如果稀缺资源是CPU,则为多个处理器内核;如果稀缺资源是支持更多并发连接的更好的数据库是连接受限的数据库等)。
另一种方式把它是:允许操作系统交错单个资源的使用情况两个任务不能是不是仅仅让一个任务中使用的资源,而其他等待,然后让第二个任务完成快连续。此外,交织的调度器成本意味着在任何实际情况下,它实际上会造成放缓。 CPU,网络资源,内存资源,外围设备或任何其他系统资源是否发生交叉使用并不重要。
来源
2015-06-01 00:22:47
ely
简短的回答:它更多的是每个连接有一个线程的开销。非阻塞的io可以避免每个连接都有一个线程。 – 2011-12-17 17:03:25
在一个系统中,阻塞IO的成本很高,因为您不能创建与连接数量相同的线程。在JVM上,您可以创建几千个线程,但如果连接数超过100.000,该怎么办?所以你必须坚持一个异步解决方案。但是,有些线程并不昂贵的语言(例如绿色线程),就像Go/Erlang/Rust那样,如果线程数不超过100.000,就不会有问题。当线程数量可能很大时,我认为阻塞IO可以缩短响应时间。但那也是我不得不问专家是否在现实中成立的原因。 – OlliP 2014-03-08 09:55:42
@OliverPlow,我也这么认为,因为阻止IO通常意味着我们让* system *处理“并行管理”,而不是使用任务队列等自己完成它。 – Pacerier 2014-06-18 19:22:11