C++ 64 bit int: pass by reference or pass by value

后端 未结 5 1112
悲哀的现实
悲哀的现实 2020-12-31 05:46

This is an efficiency question about 64 bit ints. Assuming I don\'t need to modify the value of a \"int\" parameter, should I pass it by value or reference.

Assu

相关标签:
5条回答
  • 2020-12-31 06:01

    Pass them as a boost::call_traits<int64_t>::param_type. This template captures the best practices for passing any type on the supported platforms. Hence, it will be different on 32 and 64 bits platforms, but you can use the same code everywhere. It even works inside other templates where you don't know the precise type yet.

    0 讨论(0)
  • 2020-12-31 06:05

    For argument's sake, lets ignore the trivial case of optimisers removing differences. Let's also say you're using Microsoft's Intel 64-bit calling conventions (which do differ from the Linux ABI), then you've got 4 64-bit registers for passing such values before you have to resort to pushing them on the stack. That's clearly better.

    For a 32-bit app, by value and they'd go straight onto the stack. By-reference may instead put a pointer in a register (again, a few such register uses are allowed before resorting to the stack). We can this in some output from g++ -O3 -S, calling f1(99) by value and f2(101) by const reference:

    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!?!
    

    The called function would then have to retrieve before first usage (if any). The called function's free to cache the values read in registers, so that's only needed once. With the stack approach, the value can be reread at will, so the register need not be reserved for that value. With the pointer approach, either the pointer or 64-bit value may need to be saved somewhere more predictable (e.g. pushed, or another less useful register) should that register need to be freed up momentarily for some other work, but the 64-bit int parameter be needed again later. All up, it's hard to guess which is faster - may be CPU/register-usage/optimiser/etc dependent, and it's not worth trying.

    A node to pst's advice...

    "efficiency" :( KISS. pass it how you pass every other bloody integer. - pst

    ...though, sometimes you apply KISS to template parameters and make them all const T& even though some may fit in registers....

    0 讨论(0)
  • 2020-12-31 06:14

    Use a little common sense,

    1. if the object requires a complex copy constructor, it's probably worth passing by reference (saying that - quite a lot of boost's objects are designed to be passed-by-value rather than reference simply because internal implementation is quite trivial) There is one odd one which I haven't really worked out, std::string, I always pass this by reference...

    2. If you intend to modify the value that is passed in, use a reference

    3. Else, PASS-BY-VALUE!

    Do you have a particular performance bottleneck with arguments to functions? Else, don't spend too much time worrying about which is the best way to pass...

    Optimizing by worrying about how an int is passed in is like pi**ing in the sea...

    0 讨论(0)
  • 2020-12-31 06:15

    Pass by value - definitely. If the system is 64-bit it means it copies 64-bit word extremely fast.

    0 讨论(0)
  • 2020-12-31 06:15

    Even on a 64 bit machine pass by value is better (with some very few exceptions), because it can be passed as a register value.

    0 讨论(0)
提交回复
热议问题