Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 缓存一致性:线程与核心_Multithreading_Caching_Concurrency - Fatal编程技术网

Multithreading 缓存一致性:线程与核心

Multithreading 缓存一致性:线程与核心,multithreading,caching,concurrency,Multithreading,Caching,Concurrency,我目前正在研究并发系统,当同时处理多个线程和多个内核时,我对缓存一致性的概念有点困惑 据我所知,有些假设: 内核有缓存 如果超线程,内核可能一次有多个线程 线程是正在处理的一行命令 因此,线程不是物理硬件,线程没有缓存并且使用内核的缓存 假设一个核心有两个线程,x是一个值为5的共享变量。双方都希望执行: 我的y=x 其中my_y是由两个线程定义的私有变量。现在假设线程0执行: x++ 最后,假设线程1现在执行: 我的z=x 其中my_z是另一个私有变量 我的书是这样写的: 我的z值多少?是五点吗

我目前正在研究并发系统,当同时处理多个线程和多个内核时,我对缓存一致性的概念有点困惑

据我所知,有些假设:

内核有缓存 如果超线程,内核可能一次有多个线程 线程是正在处理的一行命令 因此,线程不是物理硬件,线程没有缓存并且使用内核的缓存 假设一个核心有两个线程,x是一个值为5的共享变量。双方都希望执行:

我的y=x

其中my_y是由两个线程定义的私有变量。现在假设线程0执行:

x++

最后,假设线程1现在执行:

我的z=x

其中my_z是另一个私有变量

我的书是这样写的:

我的z值多少?是五点吗?还是六点?问题是x至少有三个副本:一个在主内存中,一个在线程0的缓存中,另一个在线程1的缓存中

这是怎么回事?为什么x至少有三个副本?为什么书中指定每个线程都有自己的缓存?对我来说,运行这两个线程的核心在其缓存中具有x值是有意义的,因此这两个线程在其共享缓存中都具有x值

换句话说,当x++被更新时,核心缓存中的值将被更新。然后,线程1将执行my_z=x;它仍然在内核的缓存中,并且是最新的。因此,不存在一致性问题,因为两个线程基本上共享缓存

这可能是因为本书假设每个核心只有一个线程,但本书之前确实提到了线程是否多于核心的问题。如果线程多于内核,是否意味着一个内核有多个线程超线程,或者是否存在某种线程调度,使得每个内核一次只有一个线程

即使在这种情况下,内核的调度和一个内核一次只能有一个线程,如果一个内核拥有线程0,执行x++然后获得试图执行my_z=x的线程1;如果我没弄错的话,x的值仍然存在于核心的缓存中

附加问题:线程的私有变量如何存储在内存中?它们的存储方式是否与使用时复制到核心缓存中的任何变量相同?如果是这种情况,那么如果多个线程同时或计划使用缓存,那么在内核的缓存中有一个私有变量会有问题吗

根据@biziclop的要求,本书陈述了以下假设:

我们使用MIMD系统,即节点具有相同的体系结构。不过,这本书并没有具体说明这是哪种体系结构 我们的程序是SPMD。因此,我们将编写一个可以使用分支实现多种行为的程序。 我们假设内核是相同的,但异步运行。 我们使用C语言编程,在本节中,我们重点介绍Pthreads。 任何帮助都将不胜感激

为什么书中指定每个线程都有自己的缓存

作者太马虎了。线程没有缓存。运行线程的处理器内核具有缓存

这本书以前曾说过,如果线程多于内核。这是否意味着一个内核有多个线程超线程,或者是否存在某种线程调度,使得每个内核一次只有一个线程

这两件事中的任何一件都可能是真的。我们已经确定作者的语言有点草率,所以把这句话从上下文中去掉,我们无法判断这句话所说的是硬件线程多于内核还是软件线程

线程的私有变量如何存储在内存中

进程中的所有线程都可以看到相同的虚拟地址空间。从最广泛的意义上讲,private只是描述一个仅由一个线程使用的内存位置,而为什么该位置仅由一个线程使用并不重要

在更狭义的意义上,每个线程都有一个函数激活记录堆栈,即包含所有活动函数调用的参数和局部变量的调用堆栈。在许多编程语言中,一个线程不可能与任何其他线程共享其参数或局部变量,因此这些内存位置自动是私有的。在其他编程语言中,共享arg或local是可能的,但是程序员必须编写显式代码来共享它,而且在任何情况下,这可能都不是一个好主意

如果多个线程同时或计划使用缓存,那么在内核的缓存中有一个私有变量会有问题吗

当两个不同的内存位置都散列到同一个缓存位置时,这称为碰撞 在…上是啊!碰撞有时会发生。如果某个缓存线包含变量X,而线程T希望访问恰好使用同一缓存线的变量Y,那么内存系统将使线程T在从主内存获取数据时等待


这种现象通常在出现问题时也被称为虚假共享,如果确定它确实降低了程序的性能,您可以通过谷歌搜索策略来避免这种现象。

不要忘记,在高度优化的代码中,变量通常存储在寄存器中的时间长得惊人,独立于任何一级或二级缓存。不过,如果你能具体说明我们讨论的是什么语言/体系结构,那会有所帮助。谢谢,@biziclop。我已经在我的帖子中添加了更多信息。IMO,如果你不是在学习设计计算机硬件,那么在你的职业生涯中,尝试理解超线程的微妙之处可能还为时过早。如果您编写的代码将在某些多处理器操作系统下以用户模式运行,那么您将无法控制在任何给定时刻哪个内核的哪个硬件线程将运行您的代码。如果你根据你选择的任何编程语言的内存模型来编写代码,那么无论操作系统选择哪个硬件资源来运行你的程序线程,它都会正确运行。完美的解释。谢谢。一些作者可能会使用线程缓存,其含义更广泛,线程可以主动缓存全局内存视图中的任何内容。在Java中,允许线程保留非易失性变量的私有副本,即使在看到新的变量值后也不更新它:没有一致性。