Я должен передать много указателей в своем коде посреди большого цикла (поэтому у меня есть много выражений, таких как foo(&x, &y, ...)
). Мне было интересно, должен ли я хранить указатели как отдельные переменные (т.е. кеш) для производительности (за счет введения большего количества переменных и беспорядка в моем коде)?
(Делая много матричного мульт., А библиотека CUBLAS настаивает на указателях …)
Нет — адрес оператора примерно такой же недорогой / быстрый, как и все, на что вы можете надеяться. Это возможный перегрузить его, и такая перегрузка мог быть медленнее, но перегрузить его вообще довольно необычно.
std::addressof
не несет никакого штрафа вообще. Когда все сводится к ассемблерному коду, мы в любом случае обращаемся к объектам только по их адресам, поэтому информация уже имеется.
Что касается operator&
, это зависит от того, был ли он перегружен или нет. Оригинальная, не перегруженная версия ведет себя так же, как std::addressof
, Однако если operator&
был перегружен (что в любом случае является очень плохой идеей и довольно неодобрительно), все ставки сняты, так как мы не можем угадать, какой будет перегруженная реализация.
Таким образом, ответ на ваш вопрос: нет необходимости хранить указатели отдельно, вы можете просто использовать std::addressof
или же operator&
всякий раз, когда они вам нужны, даже если вам нужно это повторить.
в C ++ есть ссылки, то, что вы описываете, звучит скорее как поведение для языка C, а не C ++.
Такая сигнатура для методов C ++ обычно реализуется, чтобы избежать копирования, по умолчанию, когда вы вызываете метод и передаете ему несколько аргументов, эти аргументы генерируют локальную копию, имея ссылки, это техника, которая помогает вам избежать этих издержек для копии.
Это было бы очень эффективно. Если вы используете 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_>
Ссылка в этом случае фактически такая же, как указано выше.