异步程序显示引用的位置?

时间:2010-09-27 03:51:54

标签: asynchronous

我正在阅读这篇优秀文章,其中介绍了异步编程http://krondo.com/blog/?p=1209,并且我遇到了以下难以理解的内容。

由于没有实际的并行性(在asnyc中),从我们的图中可以看出异步程序与同步程序执行的时间一样长,可能更长,因为异步程序可能会表现出来较差的参考地点。

有人可以解释一下这里的参考地点是如何形成的吗?

2 个答案:

答案 0 :(得分:5)

维基百科文章提到的参考地点是观察到当访问某些数据时(在磁盘上,在内存中,无论如何),通常也会访问该位置附近的其他数据。这种观察是有道理的,因为开发人员倾向于将类似的数由于数据是相关的,因此它们经常被一起处理。具体来说,这被称为空间局部性。

对于一个弱的例子,想象一下计算数组的总和或进行矩阵乘法。表示数组或矩阵的数据通常存储在连续的内存位置,对于此示例,一旦访问内存中的某个特定位置,您也将访问靠近它的其他位置。

计算机体系结构考虑了引用的位置。操作系统具有“页面”的概念,它是(大致)4KB数据块,可以单独分页(在物理内存和磁盘之间移动)。当你触摸一些不驻留的内存(不是物理上在RAM中)时,操作系统会将整个数据页从磁盘上移到内存中。原因在于地点:您可能会触及您刚触及的其他数据。

此外,CPU具有缓存的概念。例如,CPU可能具有L1(1级)高速缓存,这实际上只是CPU可以比RAM访问速度快的CPU数据块。如果值在L1高速缓存中,则CPU将使用该值而不是外出到RAM。遵循引用局部性的原则,当CPU访问主存储器中的某个值时,它会将该值及其附近的所有值带入L1高速缓存。这组值称为缓存行。缓存行的大小各不相同,但重点是当您访问数组的第一个值时,CPU可能必须从RAM中获取它,但随后的访问(接近关闭)会更快,因为CPU带来了整个数据包在第一次访问时将值放入L1缓存中。

所以,回答你的问题:如果你想象一个同步过程计算一个非常大的数组的总和,它将依次触摸内存位置。在这种情况下,你的地方是好的。但是,在异步情况下,您可能会有n个线程,每个线程都会获取一个数组(大小为1/n)并计算子总和。每个线程正在触及存储器中可能非常不同的位置(因为阵列很大),并且由于每个线程可以切换进出执行,因此从OS或CPU的角度来看,实际的数据访问模式很差。 CPU上的L1缓存是有限的,因此如果线程1引入缓存行(由于访问),这可能会驱逐线程2的缓存行。然后,当线程2访问其数组值时,它必须转到RAM,它将再次引入其缓存行并可能驱逐线程1的缓存行,依此类推。根据系统资源和整体使用情况,此模式也可能在OS /页面级别上发生。

答案 1 :(得分:1)

较差的引用位置导致较慢的缓存使用 - 每次进行线程切换时,您可以预期缓存中的大部分内容与之前的线程相关,而不是当前线程,因此大多数读取将获取数据从主内存而不是缓存。

他最终错了,至少对于不少节目而言。原因很简单:即使您在CPU绑定代码上没有获得任何结果,当您可以将一些CPU绑定代码与一些I / O绑定代码组合在一起时,您可以期望整体速度提高。例如,您可以启动读取或写入,然后在磁盘忙时切换到执行计算,然后在磁盘完成其工作时切换回I / O绑定线程。