Подтвердить что ты не робот

С++ 64 бит int: передавать по ссылке или передавать по значению

Это вопрос эффективности 64-битных int. Предполагая, что мне не нужно изменять значение параметра "int", следует передать его по значению или ссылке.

Предполагая 32-битную машину:

1) 32-разрядный int: Я думаю, что ответ "pass by value", поскольку "pass by reference" будет иметь накладные расходы на дополнительный поиск в памяти.

2) 64-битный int: если я передаю по ссылке, я передаю только 32-разрядный адрес в стеке, но нуждаюсь в дополнительном поиске в памяти. Итак, какой из них лучше (ссылка или значение)?

Что делать, если машина 64 бит?

С уважением,

В JP

4b9b3361

Ответ 1

Перейдите по значению - определенно. Если система 64-битная, это означает, что она быстро копирует 64-битное слово.

Ответ 2

Даже на 64-битной машине пропуск по значению лучше (с некоторыми очень немногими исключениями), потому что он может быть передан как значение регистра.

Ответ 3

Передайте их как boost::call_traits<int64_t>::param_type. Этот шаблон отражает лучшие методы передачи любого типа на поддерживаемых платформах. Следовательно, это будет отличаться на 32 и 64 битных платформах, но вы можете использовать один и тот же код везде. Он даже работает внутри других шаблонов, где вы еще не знаете точного типа.

Ответ 4

В целях аргумента давайте проигнорируем тривиальный случай устранения различий оптимизаторов. Предположим также, что вы используете Microsoft 64-разрядные соглашения о вызовах (которые отличаются от Linux ABI), тогда у вас есть 4 64-разрядных регистра для передачи таких значений, прежде чем вам придется прикладывать их к стеку. Это явно лучше.

Для 32-битного приложения по значению, и они попадут прямо в стек. Вместо ссылки вместо этого указывается указатель в регистре (опять же, до тех пор, пока не прибегают к стеку, разрешается использование нескольких таких регистров). Мы можем это сделать в некоторых выводах из g++ -O3 -S, вызывая f1 (99) по значению и f2 (101) по ссылке const:

void f1(int64_t);
void f2(const int64_t&);

int main()
{
    f1(99);
    f2(101);
}

...

    pushl   0
    pushl   $99
    call    _Z2f1x    // by value - pushed two halves to stack

    leal    -8(%ebp), %eax
    movl    %eax, (%esp)
    movl    $101, -8(%ebp)
    movl    $0, -4(%ebp)
    call    _Z2f2RKx   // by const& - ugly isn't it!?!

Вызываемая функция затем должна быть извлечена перед первым использованием (если она есть). Вызываемая функция позволяет кэшировать значения, считанные в регистрах, так что требуется только один раз. При подходе к стеку значение может быть перечитано по желанию, поэтому регистр не должен быть зарезервирован для этого значения. При использовании указателя указатель или 64-битное значение, возможно, нужно будет сохранить где-то более предсказуемым (например, нажатым или другим менее полезным регистром), чтобы этот регистр необходимо было мгновенно освободить для какой-либо другой работы, но 64-разрядный параметр int потребуется позже. Все, трудно догадаться, что быстрее - может быть зависимо от CPU/register-usage/optimiser/etc, и это не стоит пытаться.

A node to pst advice...

"эффективность": (KISS) передайте его, как вы проходите каждое другое кровавое целое. - pst

... хотя иногда вы применяете KISS к параметрам шаблона и делаете их все const T & хотя некоторые могут поместиться в регистры....

Ответ 5

Используйте немного здравого смысла,

  • если для объекта требуется сложный конструктор копирования, возможно, стоит перейти по ссылке (говоря, что - довольно много объектов boost предназначены для передачи по значению, а не для ссылки просто потому, что внутренняя реализация довольно тривиальная ) Есть один нечетный, который я на самом деле не разработал, std::string, я всегда передаю это по ссылке...

  • Если вы намерены изменить переданное значение, используйте ссылку

  • Else, PASS-BY-VALUE!

У вас есть узкое место производительности с аргументами для функций? Кроме того, не тратьте слишком много времени на то, чтобы беспокоиться о том, что это лучший способ пройти...

Оптимизация, беспокоясь о том, как передается int, похожа на pi ** ing в море...