Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do inline lambdas suffer the same latency of function pointer indirect addressing

Tags:

c++

c++11

lambda

// approach 1
template <typename T>
void f1(T t, int a, int b) {
   t(a, b);
}

// approach 2
void f2(void(*g)(int, int), int a, int b) 
{
   g(a, b); 
}

void g (int a, int b) 
{
    // do something
}

int main() 
{
   f1([](int a, int b)
         { 
           //do something 
         }, 1, 2);

   f2(&g, 1, 2);
}

My question is, do f1 and f2 suffer from the same indirect addressing latency to get the address of the function to be executed (given that the lambda is implemented as a function object)?

What if the lambda was not inline?

Note: I declared the function f1 as template to leave the deduction of the parameter lambda type to the compiler (instead of enforcing an std function for example, not sure if it makes a difference though).

like image 882
mkmostafa Avatar asked Jan 05 '17 14:01

mkmostafa


2 Answers

Conceptually the compiler should be able to inline the lambda body. Using a lambda is a compile time thing, that means the compiler knows exactly what function you are going to call and thus it should be able to inline the code. With a function pointer the function passed is not really known until run time so the compiler has much more work to do to try and see if can inline it. Generally the code is not inlined and you have an indirection through the pointer.

like image 157
NathanOliver Avatar answered Nov 12 '22 09:11

NathanOliver


does f1 and f2 suffer from the same indirect addressing latency to get the address of the function to be executed (given that the lambda is implemented as a function object)?

The standard doesn't specify any guarantees about latencies. But there isn't any reason the lambda call to have any more latency than a call to a regular inline function. It is possible for the compiler to determine the address of the generated function at compile time, and no indirection is necessary.

Calling a function pointer may require overhead from the indirection, unless the function has been expanded inline in which case the value of the pointer may be known at compile time in the expanded context.

what if the lambda was not inline?

You cannot declare a lambda, and define it in another compilation unit. All lambdas are inline.

Note: I declared the function f1 as template to leave the deduction of the parameter lambda type to the compiler (instead of enforcing an std function for example, not sure if it makes a difference though).

std::function has at least as much overhead as a function pointer does.

like image 24
eerorika Avatar answered Nov 12 '22 07:11

eerorika