相关疑难解决方法(0)

为什么内存重新排序在单核/处理器机器上不是问题?

考虑以下取自维基百科的示例,稍作修改,其中程序的步骤对应于各个处理器指令:

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

5
推荐指数
2
解决办法
441
查看次数

MOESI缓存一致性协议相对于MESI有什么好处?

我想知道MOESI相对于MESI缓存一致性协议有什么好处,以及哪种协议目前最受现代体系结构的青睐。如果成本不允许,收益通常不会转化为实施。MOESI在MESI上的定量性能结果也很高兴看到。

memory multithreading caching memory-management cpu-architecture

4
推荐指数
2
解决办法
1425
查看次数

用于线程之间数据交换的内容是在一个Core上用HT执行的?

超线程技术是英特尔推出的一种同步多线程技术.

这些资源包括执行引擎,缓存和系统总线接口; 资源共享允许两个逻辑处理器更有效地相互协作,并允许停滞的逻辑处理器从另一个逻辑处理器借用资源.

在具有超线程的Intel CPU中,一个CPU内核(具有多个ALU)可以在同一时钟执行来自2个线程的指令.两个线程共享:存储缓冲区,缓存L1/L2和系统总线.

但是如果两个线程在一个Core上同时执行,则thread-1存储原子值,而thread-2加载此值,将用于此交换的内容:共享存储缓冲区,共享缓存L1/L2还是通常的缓存L3?

如果两个线程来自同一个进程(相同的虚拟地址空间)和两个不同进程(不同的虚拟地址空间),会发生什么?

Sandy Bridge Intel CPU - 缓存L1:

  • 32 KB - 缓存大小
  • 64 B - 缓存行大小
  • 512 - 行(512 = 32 KB/64 B)
  • 8路
  • 64 - 数组方式(64 = 512行/ 8路)
  • 6位[11:6] - 虚拟地址(索引)定义当前集合号(这是标记)
  • 4 K - 每个相同(虚拟地址/ 4 K)竞争同一组(32 KB/8路)
  • 低12位 - 对于确定当前设定数值很重要

  • 4 KB - 标准页面大小

  • 低12位 -每个地址的虚拟和物理地址相同

在此输入图像描述

concurrency x86 multithreading x86-64 hyperthreading

3
推荐指数
1
解决办法
721
查看次数

Intel 64 和 IA-32 上的 MESI 有何意义

  • MESI 的要点是保留共享内存系统的概念。
  • 然而,对于存储缓冲区,事情就变得复杂了:
  • 一旦数据到达 MESI 实现的缓存,下游内存就会保持一致。
  • 然而,在此之前,每个核心可能对内存位置 X 中的内容存在分歧,具体取决于每个核心的本地存储缓冲区中的内容。
  • 因此,从每个核心的角度来看,内存的状态似乎是不同的——它是不连贯的。
  • 那么,为什么我们要“部分地”强制执行与 MESI 的一致性呢?

编辑:在进一步缩小真正让我困惑的内容之后,进行了实质性编辑。我试图保持问题的一般概念不变,以保留收到的优秀答案的相关性。

concurrency x86 caching cpu-architecture mesi

3
推荐指数
1
解决办法
978
查看次数

为什么错误共享仍然影响非原子,但远小于原子?

考虑以下证明错误共享存在的示例:

\n\n
using 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\n
Run Code Online (Sandbox Code Playgroud)\n\n

一个线程a以 1 为步长递增,另一个线程以 1 为步长递增b。增量编译为lock xaddMSVC,即使结果未使用。

\n\n

a对于和分开的结构b,几秒钟内累积的值大约是 的not_shared_t十倍shared_t

\n\n

到目前为止的预期结果:单独的缓存行在 L1d 缓存中保持热状态,增加lock xadd吞吐量瓶颈,错误共享是缓存行乒乓球的性能灾难。(编者注:更高版本的 MSVClock inc在启用优化时使用。这可能会扩大竞争与非竞争之间的差距。)

\n\n
\n\n

现在我using type = std::atomic<std::int64_t>;用普通的替换std::int64_t

\n\n

(非原子增量编译为inc QWORD PTR [rcx]。循环中的原子加载恰好阻止编译器将计数器保留在寄存器中,直到循环退出。)

\n\n

达到的计数not_shared_t仍大于 的计数shared_t,但现在少于两倍。 …

c++ x86 cpu-architecture cpu-cache false-sharing

3
推荐指数
1
解决办法
481
查看次数

当不同CPU核心在没有同步的情况下写入相同的RAM地址时会发生什么?

假设2个内核试图在相同的时刻(正负eta)将不同的值写入相同的RAM地址(1个字节),并且不使用任何互锁指令或内存屏障.在这种情况下会发生什么以及将什么值写入主RAM?第一个获胜?最后一个获胜?不确定的行为?

x86 multithreading cpu-architecture low-level lock-free

2
推荐指数
1
解决办法
295
查看次数

当核心在其L1缓存中写入而另一个核心在其L1中具有相同的行时会发生什么?

当核心在其L1缓存中写入而另一个核心在其L1中具有相同的行时会发生什么?

让我们说一下英特尔Skylake CPU.

缓存系统如何保持一致性?它是否实时更新,是否会阻止其中一个核心?使用两个内核连续写入相同缓存行的性能成本是多少?

cpu-cache

1
推荐指数
1
解决办法
96
查看次数

Intel X86如何实现全店排序

由于其 TSO 内存模型,X86 保证所有商店的总顺序。我的问题是是否有人知道这是如何实际实施的。

我对所有 4 个围栏是如何实现的印象很好,所以我可以解释如何保留本地秩序。但是 4 个栅栏只会给 PO;它不会给您 TSO(我知道 TSO 允许旧商店跳到新负载前面,因此只需要 4 个围栏中的 3 个)。

单个地址上所有内存操作的总顺序是一致性的责任。但我想知道英特尔(特别是 Skylake)如何在多个地址的商店上实现总订单。

x86 intel cpu-architecture memory-barriers micro-architecture

1
推荐指数
1
解决办法
511
查看次数