在一个大循环中,我必须在我的代码中传递很多指针(所以我有很多表达式,比如foo(&x, &y, ...)
)。我想知道是否应该将指针存储为单独的变量(即缓存)以提高性能(以在代码中引入更多变量和混乱为代价)?
(做很多矩阵 mult。CUBLAS 库坚持使用指针......)
在一个大循环中,我必须在我的代码中传递很多指针(所以我有很多表达式,比如foo(&x, &y, ...)
)。我想知道是否应该将指针存储为单独的变量(即缓存)以提高性能(以在代码中引入更多变量和混乱为代价)?
(做很多矩阵 mult。CUBLAS 库坚持使用指针......)
不 - 操作员的地址与您希望的任何东西一样便宜/快速。它可能会超载,而且这种超载可能会更慢,但完全超载它是相当不寻常的。
std::addressof
根本不会受到任何惩罚。当它归结为汇编代码时,无论如何我们只通过它们的地址引用对象,因此信息已经在手边。
关于operator&
,这取决于它是否已超载。原始的非重载版本的行为与std::addressof
. 但是,如果operator&
已经重载(无论如何这是一个非常糟糕的主意,并且非常不受欢迎),那么所有的赌注都没有了,因为我们无法猜测重载的实现将是什么。
所以你的问题的答案是:不需要单独存储指针,你可以使用std::addressof
或operator&
在需要时使用它们,即使你必须重复它。
这将非常有效。如果您使用的是 Linux,则可以使用 objdump 进行检查。以下是 fooP(&var1, &var2) 在 x86 架构中的样子。它只不过是一条 LEA 指令。
fooP(&var1, &var2);
8048642: 8d 44 24 1c lea 0x1c(%esp),%eax -> this is to get the address of var2 to eax
8048646: 89 44 24 04 mov %eax,0x4(%esp) -> this is to save the address to the stack for later fooP call
804864a: 8d 44 24 18 lea 0x18(%esp),%eax -> address of var1
804864e: 89 04 24 mov %eax,(%esp)
8048651: e8 be ff ff ff call 8048614 <_Z4fooPPiS_>
本例中的引用实际上与上述相同。
在 C++ 中有引用,你所描述的听起来更像是 C 语言而不是 C++ 的行为。
这种 C++ 方法的签名通常是为了避免复制而实现的,默认情况下,当您调用方法并向其传递一些参数时,此参数会生成一个本地副本,引用它是一种帮助您避免复制开销的技术。