Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Who pays the cost for not passing by const reference

Tags:

c++

Given:

void foo(std::vector<int> v);

void bar()
{
    std::vector<int> v = ...; // many items
    foo(v);
}

What in a profiling tool would show as the hot path? Would it be the std::vector<T>'s copy constructor, the runtime or the operating system? I remember in school (I'm not a C++ dev, just work with some) that this will copy v and that can take time. I do know that a signature like:

void foo(const std::vector<int>& v);

avoids this potentially costly copy operation.

like image 346
Daniel A. White Avatar asked Aug 03 '16 10:08

Daniel A. White


1 Answers

Copying std::vector<T> by value does, potentially, three things:

  1. Memory manager (C++ runtime or custom allocator) searches for available memory block for the new vector in its stashes. If it can find it, then it goes to step #3.
  2. Memory manager (C++ runtime or custom allocator) requests more memory from the OS. This call itself is relatively cheap (as much as a syscall can be), because the OS gives memory in lazy mode - actual allocation is happening on the first write to the requested VM page.
  3. Compiler generated code (application) does in-place new with copy c-tor for each element in the new vector if T is not trivially copy-constructible. Otherwise, memcpy() or it's optimized vectorized (in sse sense) counterpart is called. Just before the first time the new memory is written, if it was acquired from the OS in #2, the OS will need to actually allocate the new VM page and that may trigger RAM access (hardware), TLB lookup (hardware + OS) swapping in/out (OS).

In your specific example T is trivially copy-constructible so the worst case overhead would be C++ runtime memory block lookup + sbrk() syscall + memcpy() call.

like image 168
bobah Avatar answered Sep 24 '22 14:09

bobah