【问题标题】:C/C++ programming about read/wri关于读/写的 C/C++ 编程
【发布时间】:2021-02-26 11:25:20
【问题描述】:

我开始想一些关于内存读写的基本思路(假设我们读写的数据还没有被缓存)。

对于以下代码:

int a = 1;

肯定是写,因为我们将值'1'写入变量'a'的内存位置。

但是对于以下代码:

int a, b;
a = 1;
b = a;

当我们执行语句“b = a;”时,我们真的执行了一次读取和一次写入吗? 根据我的理解,我认为是一读一写,因为我们必须先加载 'a' 的值,然后将值写入 'b'。

不确定我的理解是否正确。请帮助我澄清这些基本概念。 非常感谢您的帮助。

【问题讨论】:

  • 将高级 C 代码视为“读取”和“写入”或“此代码必须执行 x 次读取和 y 次写入”是没有意义的。这不是它的工作原理——重要的是编译器如何将 C 代码转换为机器代码,这是一个很大的话题。如果你想学习这些东西,你应该学习一门汇编语言。

标签: c memory read-write


【解决方案1】:

假设我们读取或写入的数据还没有被缓存)

我看不出缓存与此有何关联。

当我们执行语句“b = a;”时,我们真的执行了一次读取和一次写入吗?

正确。

但是,C 不像汇编语言。 C 指令不会一对一映射到机器指令。有the as-if rule。基本上,只要保留程序的可观察行为,编译器就可以生成任何机器代码。

例如:

auto foo()
{
    int a = 24;
    int b = 11;
    int c = a + b;

    return c;
}

C编译器可以随意把上面的编译成

foo():
        mov     eax, 35
        ret

编译器确实会这样做(启用优化)。如您所见,没有内存读/写。只需写入eax 寄存器(必须放置函数的返回)。并且值是立即数 (35)。

【讨论】:

  • 谢谢,我明白优化可以在一定程度上改变编译器的行为。假设编译时没有这样的优化,我们可以假设代码b = a;是一种一读一写,对吧?另外,我刚刚发现 Compiler Explorer 网站可以帮助将 C 代码转换为 Assembely(查看此链接:godbolt.org/z/8G13Ps)。所以我们提到的读写只是Assembly中的mov,对吧?
  • @WentaoHuang,在生成的机器代码中读取和写入内存之间存在差异,如果是 C 程序,则读取和写入(抽象)变量。它们不是一回事:在上面的示例中,变量abc 甚至不存在于生成的机器代码中。至于那个godbolt示例,请尝试在右上角的编译器选项中添加-O2-O3...
  • "我们可以假设代码 b = a; 是一种一读一写,对吧" 不!您不能假设高级代码。在这种情况下,编译器分配这些变量的位置很重要:在寄存器中、堆栈上或专用内存地址。这 3 个场景中的每一个都会产生不同的代码。例如,CPU 可能必须先将值加载到寄存器中,然后再将它们存储到其他位置。
  • @Lundin,所以我们可以假设它是一次加载和一次存储吗?
  • @WentaoHuang “你不能假设高级代码。”
猜你喜欢
  • 1970-01-01
  • 2015-04-01
  • 2011-05-20
  • 2010-12-31
  • 1970-01-01
  • 2011-01-11
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多