Multithreading 为什么存在弱记忆模型?它们的指令顺序是如何选择的?

Multithreading 为什么存在弱记忆模型?它们的指令顺序是如何选择的?,multithreading,memory,parallel-processing,memory-model,Multithreading,Memory,Parallel Processing,Memory Model,ARM等CPU具有弱内存模型。假设我们有两个线程T1和T2 | T1 | T2 | |---------|---------| | Instr A | Instr C | | Instr B | Instr D | 在弱顺序中,任何指令都可以在任何时间运行,这意味着“D->a->B->C”是可能的 我的第一个问题是为什么这是有益的?我的第二个问题是如何进行选择(优化)?CPU是随机选取的还是有算法支持?是CPU在拣选,还是有另一个芯片在工作(内存芯片或其他什么)?没有全局仲

ARM等CPU具有弱内存模型。假设我们有两个线程T1和T2

| T1      | T2      |
|---------|---------|
| Instr A | Instr C |
| Instr B | Instr D |
在弱顺序中,任何指令都可以在任何时间运行,这意味着“D->a->B->C”是可能的


我的第一个问题是为什么这是有益的?我的第二个问题是如何进行选择(优化)?CPU是随机选取的还是有算法支持?是CPU在拣选,还是有另一个芯片在工作(内存芯片或其他什么)?

没有全局仲裁器会做这样的事情。如果有的话,总是按顺序做事也同样有效

立即可用的唯一数据是本地数据。每次执行都基于快速可用的信息做出决策

没有按相反顺序而不是书面顺序执行任何事情的压力。保留并不是先天的好。但B的数据可能在A的数据之前可用,然后B可能会首先执行,因为等待A完成会让计算资源闲置


因此,这完全是一个在需要时提供所有数据的问题,以及处理器之间通信的延迟。您可以将其视为一种团队合作,与只能通过非常缓慢的沟通方式进行交流的人合作:他们将根据本地可用信息完成同样多的工作。没有一个中央权力机构能够准确地描述最近完成的工作的状态。

为什么会退出弱内存模型?

出于性能原因。弱内存模型允许编译器和硬件优化,从而提高系统性能。实施一项强有力的政策的成本 编译和硬件实现中的内存模型(顺序一致性模型)严重降低了性能

什么是允许的指令重新排序(如何进行选择)?

它特定于每个内存模型。有几种弱内存模型,指令重新排序规则是它们规范的一部分

指令重新排序广泛用于编译器和硬件优化,以实现更高的性能。这些优化的基本前提是,只要保持程序的功能正确性,指令就可以重新排序

在顺序(单线程)程序中,功能正确性可以通过简单地确保“如果两个操作访问相同的内存位置,并且其中一个是写操作,或者如果它们之间存在数据或控制依赖关系,则按照程序顺序执行。”


对于多线程程序,功能正确性还取决于加载和存储到同一线程中不同内存位置的相对顺序。内存型号规范规定了在不影响功能正确性的情况下对两条内存指令重新排序的条件。

除上述答案外:

如果没有围栏,则需要保留的唯一顺序是数据依赖顺序。因此,在一个CPU上,负载为X的内存应该是X之前的最新存储。但如果指令没有任何数据依赖性,它们可以按任何顺序执行

现代CPU的无序使用使得指令流中的并行性最大化。这样,独立指令可以并行运行,并防止CPU因内存访问而暂停

CPU使用其他技术,如存储缓冲区、加载缓冲区、写合并等,所有这些都可能导致加载和存储执行无序。这很好,因为它对执行这些加载和存储的核心不可见。问题是当内核与其他内核共享内存时;然后,这些重新排序可以变得可见

对于顺序一致性(SC),不允许重新排序;因此,所有4个围栏都需要保留->[LoadLoad][LoadStore][StoreLoad][StoreStoreStoreStore]

在X86上,存储缓冲区会导致旧存储与新加载一起重新排序到不同的地址;因此[StoreLoad]被删除,SC只保留[LoadLoad][LoadStore][StoreStore]。这种内存模型称为TSO(总存储顺序)

TSO可以通过允许对来自同一内核的写入进行重新排序(例如,写入合并或存储未按顺序退役的缓冲区)来放松。这将导致PMO(部分存储订单)

SC/TSO/PMO的问题是不允许某些重新排序,这会导致性能降低;假设在同一个CPU上有两个独立的负载,那么由于[LoadLoad]的原因,这些负载无法重新排序。实际上,这可以通过推测性地执行指令来解决,如果检测到无序加载,则刷新管道并重新启动。这使得CPU更复杂,性能更低

像SC、TSO、PMO这样的模型是强一致性模型,因为每次加载和每个存储都有一定的排序语义。但在弱有序一致性模型中,普通加载/存储(无排序语义)和同步操作(例如,提供排序语义的获取加载和释放存储)之间存在分离。具有获取加载和释放存储的弱内存模型称为释放一致性

这些弱模型的最大优点是允许更高程度的并行性和更简单的CPU设计。它将负担转移到软件上

在实践中,您通常使用提供特定内存模型的编程语言/API进行编程,它需要确保编译器没有违反该模型,并向硬件添加足够的顺序,例如以围栏的形式。如果您了解了Java或C11,并且正确地使用了它,那么相同的代码将在具有强内存模型(如X86)的CPU和具有弱内存模型(如ARM)的CPU上正常运行。

请参阅