使用参数的本地副本比直接使用指针参数更加缓存吗?复制的开销是否会超过获得的性能? 我想这取决于复制数据的大小。
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;
}
我声称"做东西"在堆栈上推送了很多其他局部变量。
编辑:此外,该功能应该更改/初始化数据。
编辑:这是编译器可能优化的吗?
答案 0 :(得分:2)
查看您的操作系统ABI。
让我们假设您正在运行64位Linux系统。指针是一个整数类型,前六个整数类型在函数调用期间由寄存器传递 - 到目前为止没有缓存参与。
如果你去复制你分配额外的RAM空间。在这种情况下,您的缓存是整个程序的一部分。 我会去第一个,因为它直接传递你的指针信息,并没有分配额外的RAM。
但是:如果你想测量你的程序。去找valgrind(仍然假设你正在运行linux)。
对两种变体进行编码并执行valgrind --tool=cachegrind myfile
并比较结果。虽然我真的怀疑现代CPU的区别......
答案 1 :(得分:1)
这里涉及的变量太多了,很难全部考虑它们,但让我试着概述几个重要方面:
无论是使用指针还是使用本地副本,都不应与现金存储器的观点有所区别:基于现代缓存的架构将在您需要时将数据存储在缓存中它(除非你的数据结构比缓存行更大 - 这是非常不可能的)
两种情况下生成的代码很可能是95%相同:当您从数据结构中读取或写入字段时,编译器会在本地读取它(在寄存器中或无论如何,把它放在堆栈上。不同之处在于读取/写入所有数据字段或只是其中一些数据字段。