内存模型和并发



我想了解C/C++内存模型,但我在所有的文章、博客、youtube视频中都发现"内存模型只用于并发"。。

有人能告诉我为什么会这样吗?

我知道内存模型是一种抽象,它允许程序员使用编程语言对底层内存系统进行推理(正确吗?)所以一般来说(独立于编程语言),我们不仍然需要单线程程序的内存模型吗?

谢谢!

我知道内存模型是一种抽象,它允许程序员使用程序设计语言(正确吗?)

内存一致性模型是一组规则,允许程序员从访问状态的每个单独代理(核心)的角度推断程序在执行过程中的任何时间点的可能状态,如果满足某些条件(例如没有数据争用)。

我想了解C/C++内存模型,但我发现文章、博客、youtube视频"只需要内存模型用于并发"..

有人能告诉我为什么会这样吗?

有一些规则可以被视为内存模型的一部分,也适用于单线程程序的上下文。特别是:

  • 写入同一位置后的读取将读取写入的值,而不是旧值
  • 在另一次写入同一位置之后的写入将覆盖以前写入的值
  • 对同一位置的读取之后的写入只会在读取完成后修改该位置

然而,这些规则被认为是如此基础和直观,以至于不值得在每个内存模型中说明它们。在VLIW体系结构的情况下,编译器会自动遵循这些规则。在传统体系结构的情况下,编译器(根据源代码中语句的顺序)和处理器都遵循这些规则(根据指令流的顺序)。所以基本上,陈述它们是多余的。除此之外,单线程程序没有其他有用的规则。

内存模型不适用于单线程代码的原因是,在ST代码中,您执行一个又一个语句,不存在混淆的可能性。在多线程代码中,对象的值可能会发生更改,而不会对当前线程发出警告。内存模型概念使您能够确保在所有其他线程完成更新值之后执行特定语句,或者在任何其他线程读取对象的值之前执行特定语句。

这是一个来自https://en.wikipedia.org/wiki/Memory_model_(编程)

内存模型允许编译器执行许多重要的优化。编译器优化(如循环融合)会移动程序中的语句,这可能会影响潜在共享变量的读写操作顺序。读取和写入顺序的更改可能会导致争用情况。

编译器可以更改变量的读写顺序,并且仍然保证代码片段将像按顺序执行读写一样运行。然而,如果涉及多线程,这可能会导致问题,因为读取/写入变量(而不是按代码顺序)可能会导致与多线程相关的问题。

检查以下由两个线程执行的代码,这两个线程都使用相同的变量init和value:

static int init = 0;
static int value = 0;
thread_a:
while( !init )
Sleep( 100 );
if ( value == 100 )
do something ...
thread_b:
value = 100;
init = 1;

编译器可以以不同的顺序(或并行)运行thread_b的代码,使得init在值被设置为100之前被设置为1。当使用单个线程时,这没有什么意义,但是,当多个线程检查这些变量时,这可能会导致问题。这里的内存模型解决了这个问题。

通常被称为内存模型的是指访问对象的执行的不同线程之间的交互。从这个意义上说,它完全与并发性有关。这与记忆无关。

还有一个重要的方面被称为对象模型,Stan Lippman的书是了解这一点的绝佳资源(它有点过时,但仍然非常相关)。对象模型也没有真正讨论如何访问内存。

最接近于对内存访问方式的描述是Ulrich Drepper的《每个程序员都应该知道内存》。这篇文章是关于内存的一般观点,独立于编程语言。当然,根据对象模型的不同,不同的编程语言可能隐藏与内存的直接交互。

最新更新