C ++ 64 бит int: передать по ссылке или передать по значению - PullRequest
12 голосов
/ 10 ноября 2010

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

Предполагается, что 32-разрядный компьютер:

1) 32-разрядный тип int: I думаю, ответ - «передача по значению», поскольку «передача по ссылке» будет иметь дополнительные издержкипоиск в памяти.

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

Что, если машина 64-битная?

С уважением,

JP

Ответы [ 5 ]

9 голосов
/ 10 ноября 2010

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

8 голосов
/ 10 ноября 2010

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

7 голосов
/ 10 ноября 2010

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

4 голосов
/ 10 ноября 2010

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

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

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 понадобится снова позже. В общем, трудно догадаться, что быстрее - может зависеть от процессора / использования регистра / оптимизатора / и т. Д., И не стоит пытаться.

Узел к совету PST ...

"эффективность" :( ПОЦЕЛУЙ. Передавай, как проходишь через каждое кровавое целое число. - pst

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

3 голосов
/ 10 ноября 2010

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

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

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

  3. Иначе, PASS-BY-VALUE!

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

Оптимизация с помощью беспокойства о том, как передается int, это как пи ** в море ....

...