4

大きなループの最中に、コード内で多くのポインターを渡す必要があります (そのため、 のような式がたくさんありますfoo(&x, &y, ...))。パフォーマンスのためにポインタを別の変数(つまりキャッシュ)として格納する必要があるかどうか疑問に思っていました (より多くの変数を導入し、コードを混乱させるという犠牲を払って)。

(多くの行列 mult を実行し、CUBLAS ライブラリはポインターを主張します...)

4

4 に答える 4

10

いいえ -- address-of 演算子は、期待できるものとほぼ同じくらい安価/高速です。オーバーロードすることは可能であり、そのようなオーバーロードは遅くなる可能性がありますが、オーバーロードすることはまったく珍しいことです。

于 2013-05-17T03:55:21.233 に答える
4

std::addressofペナルティは一切かかりません。アセンブリ コードに要約すると、いずれにせよアドレスを介してのみオブジェクトを参照するため、情報は既に手元にあります。

に関してoperator&は、オーバーロードされているかどうかによって異なります。オーバーロードされていない元のバージョンは、 とまったく同じように動作しstd::addressofます。ただし、operator&がオーバーロードされている場合 (これはとにかく非常に悪い考えであり、非常に眉をひそめています)、オーバーロードされた実装がどうなるかを推測できないため、すべての賭けはオフです。

したがって、あなたの質問に対する答えは次のとおりです。ポインターを個別に保存する必要はありません。繰り返しが必要な場合でも、必要なときにいつでもstd::addressoforを使用できます。operator&

于 2013-05-17T03:56:49.310 に答える
1

C++ には参照があります。あなたが説明していることは、C++ ではなく C 言語の動作のように聞こえます。

C++ メソッドのその種の署名は、通常、コピーを回避するために実装されます。デフォルトでは、メソッドを呼び出していくつかの引数を渡すと、この引数はローカル コピーを生成し、参照を持ちます。これは、コピーのオーバーヘッドを回避するのに役立つ手法です。

于 2013-05-17T03:54:57.253 に答える
1

それは非常に効率的です。Linux を使用している場合は、objdump を使用して確認できます。以下は、x86 アーキテクチャで fooP(&var1, &var2) がどのように見えるかです。それは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_>

この場合の参照は、実際には上記と同じです。

于 2013-05-17T07:36:17.833 に答える