考虑以下取自维基百科的示例,稍作修改,其中程序的步骤对应于各个处理器指令:
x = 0;
f = 0;
Thread #1:
while (f == 0);
print x;
Thread #2:
x = 42;
f = 1;
Run Code Online (Sandbox Code Playgroud)
我知道,print由于乱序执行,当线程在两个不同的物理内核/处理器上运行时,该语句可能会打印不同的值(42 或 0)。
但是我不明白为什么这在单核机器上不是问题,这两个线程运行在同一个核心上(通过抢占)。根据维基百科:
当程序在单 CPU 机器上运行时,硬件执行必要的簿记以确保程序执行时好像所有内存操作都按照程序员指定的顺序(程序顺序)执行,因此不需要内存屏障。
据我所知,单核 CPU 也会对内存访问重新排序(如果它们的内存模型很弱),那么是什么确保程序顺序被保留呢?
multithreading synchronization cpu-architecture low-level memory-barriers
我想知道MOESI相对于MESI缓存一致性协议有什么好处,以及哪种协议目前最受现代体系结构的青睐。如果成本不允许,收益通常不会转化为实施。MOESI在MESI上的定量性能结果也很高兴看到。
memory multithreading caching memory-management cpu-architecture
超线程技术是英特尔推出的一种同步多线程技术.
这些资源包括执行引擎,缓存和系统总线接口; 资源共享允许两个逻辑处理器更有效地相互协作,并允许停滞的逻辑处理器从另一个逻辑处理器借用资源.
在具有超线程的Intel CPU中,一个CPU内核(具有多个ALU)可以在同一时钟执行来自2个线程的指令.两个线程共享:存储缓冲区,缓存L1/L2和系统总线.
但是如果两个线程在一个Core上同时执行,则thread-1存储原子值,而thread-2加载此值,将用于此交换的内容:共享存储缓冲区,共享缓存L1/L2还是通常的缓存L3?
如果两个线程来自同一个进程(相同的虚拟地址空间)和两个不同进程(不同的虚拟地址空间),会发生什么?
Sandy Bridge Intel CPU - 缓存L1:
低12位 - 对于确定当前设定数值很重要
4 KB - 标准页面大小
编辑:在进一步缩小真正让我困惑的内容之后,进行了实质性编辑。我试图保持问题的一般概念不变,以保留收到的优秀答案的相关性。
考虑以下证明错误共享存在的示例:
\n\nusing type = std::atomic<std::int64_t>;\n\nstruct alignas(128) shared_t\n{\n type a;\n type b;\n} sh;\n\nstruct not_shared_t\n{\n alignas(128) type a;\n alignas(128) type b;\n} not_sh;\n\nRun Code Online (Sandbox Code Playgroud)\n\n一个线程a以 1 为步长递增,另一个线程以 1 为步长递增b。增量编译为lock xaddMSVC,即使结果未使用。
a对于和分开的结构b,几秒钟内累积的值大约是 的not_shared_t十倍shared_t。
到目前为止的预期结果:单独的缓存行在 L1d 缓存中保持热状态,增加lock xadd吞吐量瓶颈,错误共享是缓存行乒乓球的性能灾难。(编者注:更高版本的 MSVClock inc在启用优化时使用。这可能会扩大竞争与非竞争之间的差距。)
现在我using type = std::atomic<std::int64_t>;用普通的替换std::int64_t
(非原子增量编译为inc QWORD PTR [rcx]。循环中的原子加载恰好阻止编译器将计数器保留在寄存器中,直到循环退出。)
达到的计数not_shared_t仍大于 的计数shared_t,但现在少于两倍。 …
假设2个内核试图在相同的时刻(正负eta)将不同的值写入相同的RAM地址(1个字节),并且不使用任何互锁指令或内存屏障.在这种情况下会发生什么以及将什么值写入主RAM?第一个获胜?最后一个获胜?不确定的行为?
当核心在其L1缓存中写入而另一个核心在其L1中具有相同的行时会发生什么?
让我们说一下英特尔Skylake CPU.
缓存系统如何保持一致性?它是否实时更新,是否会阻止其中一个核心?使用两个内核连续写入相同缓存行的性能成本是多少?
由于其 TSO 内存模型,X86 保证所有商店的总顺序。我的问题是是否有人知道这是如何实际实施的。
我对所有 4 个围栏是如何实现的印象很好,所以我可以解释如何保留本地秩序。但是 4 个栅栏只会给 PO;它不会给您 TSO(我知道 TSO 允许旧商店跳到新负载前面,因此只需要 4 个围栏中的 3 个)。
单个地址上所有内存操作的总顺序是一致性的责任。但我想知道英特尔(特别是 Skylake)如何在多个地址的商店上实现总订单。
x86 intel cpu-architecture memory-barriers micro-architecture