C指针参数与本地副本

时间:2015-03-10 09:47:42

标签: c

使用参数的本地副本比直接使用指针参数更加缓存吗?复制的开销是否会超过获得的性能? 我想这取决于复制数据的大小。

void foo(struct data *p) {
    /* Do stuff with p ... */
}

// VS

void bar(struct data *p) {
    struct data copy = *p;
    /* Do stuff with copy ... */
    *p = copy;
}

我声称"做东西"在堆栈上推送了很多其他局部变量。

编辑:此外,该功能应该更改/初始化数据。

编辑:这是编译器可能优化的吗?

2 个答案:

答案 0 :(得分:2)

查看您的操作系统ABI。

让我们假设您正在运行64位Linux系统。指针是一个整数类型,前六个整数类型在函数调用期间由寄存器传递 - 到目前为止没有缓存参与。

如果你去复制你分配额外的RAM空间。在这种情况下,您的缓存是整个程序的一部分。 我会去第一个,因为它直接传递你的指针信息,并没有分配额外的RAM。

但是:如果你想测量你的程序。去找valgrind(仍然假设你正在运行linux)。

对两种变体进行编码并执行valgrind --tool=cachegrind myfile并比较结果。虽然我真的怀疑现代CPU的区别......

答案 1 :(得分:1)

这里涉及的变量太多了,很难全部考虑它们,但让我试着概述几个重要方面:

  1. 无论是使用指针还是使用本地副本,都不应与现金存储器的观点有所区别:基于现代缓存的架构将在您需要时将数据存储在缓存中它(除非你的数据结构比缓存行更大 - 这是非常不可能的)

  2. 两种情况下生成的代码很可能是95%相同:当您从数据结构中读取或写入字段时,编译器会在本地读取它(在寄存器中或无论如何,把它放在堆栈上。不同之处在于读取/写入所有数据字段或只是其中一些数据字段。

  3. 考虑到现代并行CPU架构,开销甚至可能不存在,实际上在某些情况下,因为编译器能够更好地对指令进行分组,所以使用本地副本的情况生成的代码可能会更快。