Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #79980 > unrolled thread

lamda-optimization

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2021-05-30 13:18 +0200
Last post2021-06-01 06:14 +0200
Articles 13 — 5 participants

Back to article view | Back to comp.lang.c++


Contents

  lamda-optimization Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-30 13:18 +0200
    Re: lamda-optimization Öö Tiib <ootiib@hot.ee> - 2021-05-30 10:00 -0700
      Re: lamda-optimization Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-30 19:20 +0200
    Re: lamda-optimization Real Troll <real.troll@trolls.com> - 2021-05-30 18:23 +0100
      Re: lamda-optimization Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-30 19:34 +0200
    Re: lamda-optimization David Brown <david.brown@hesbynett.no> - 2021-05-30 20:31 +0200
      Re: lamda-optimization Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-30 20:46 +0200
        Re: lamda-optimization Öö Tiib <ootiib@hot.ee> - 2021-05-30 12:26 -0700
          Re: lamda-optimization Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-31 06:16 +0200
    Re: lamda-optimization Marcel Mueller <news.5.maazl@spamgourmet.org> - 2021-05-31 18:33 +0200
      Re: lamda-optimization Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-31 18:50 +0200
        Re: lamda-optimization Marcel Mueller <news.5.maazl@spamgourmet.org> - 2021-05-31 20:27 +0200
          Re: lamda-optimization Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-01 06:14 +0200

#79980 — lamda-optimization

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-30 13:18 +0200
Subjectlamda-optimization
Message-ID<s8vs9d$898$1@dont-email.me>
I've just checked:

#include <iostream>

using namespace std;

int main()
{
	int i, j, k;
	auto f = [&]() -> int
	{
		return i + j + k;
	};
	cout << sizeof f << endl;
}

Can anyone tell me whether the lambda has three pointers (24 bytes
on 64 bit systems) instead of just one pointer inside the stack-frame,
which could be an easy optimization ?

[toc] | [next] | [standalone]


#79987

FromÖö Tiib <ootiib@hot.ee>
Date2021-05-30 10:00 -0700
Message-ID<9ac058df-b006-4afc-9983-294eaabd3526n@googlegroups.com>
In reply to#79980
On Sunday, 30 May 2021 at 14:18:20 UTC+3, Bonita Montero wrote:
> I've just checked: 
> 
> #include <iostream> 
> 
> using namespace std; 
> 
> int main() 
> { 
> int i, j, k; 
> auto f = [&]() -> int 
> { 
> return i + j + k; 
> }; 
> cout << sizeof f << endl; 
> } 
> 
> Can anyone tell me whether the lambda has three pointers (24 bytes 
> on 64 bit systems) instead of just one pointer inside the stack-frame, 
> which could be an easy optimization ?

C++ standard does not require any optimizations there so the
question is about quality of implementation (QOI). QOI questions do
not make sense without mentioning implementation name and
version. 

I suspect most compilers are turning your program into equivalent of 

int main()  {  std::cout << 42 << std::endl; }

The 42 there being unlikely but valid by standard. 
Even if you used it then most compilers would probably inline call of it
and so the number would be again meaningless.

[toc] | [prev] | [next] | [standalone]


#79991

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-30 19:20 +0200
Message-ID<s90hh3$2u8$1@dont-email.me>
In reply to#79987
>> I've just checked:
>>
>> #include <iostream>
>>
>> using namespace std;
>>
>> int main()
>> {
>> int i, j, k;
>> auto f = [&]() -> int
>> {
>> return i + j + k;
>> };
>> cout << sizeof f << endl;
>> }
>>
>> Can anyone tell me whether the lambda has three pointers (24 bytes
>> on 64 bit systems) instead of just one pointer inside the stack-frame,
>> which could be an easy optimization ?

> C++ standard does not require any optimizations there so the
> question is about quality of implementation (QOI). QOI questions
> do not make sense without mentioning implementation name and
> version.
> I suspect most compilers are turning your program into equivalent of
> int main()  {  std::cout << 42 << std::endl; }

I think you don't understand what I'm asking for.

> The 42 there being unlikely but valid by standard.

No, 24.
And my question is why the compiler doesn't do the simple
optimization of storing just a single pointer inside the
stackframe inside the lambda-object. That would result in
less memory-accesses and it would save registers.

[toc] | [prev] | [next] | [standalone]


#79992

FromReal Troll <real.troll@trolls.com>
Date2021-05-30 18:23 +0100
Message-ID<s90hs9$1unc$1@gioia.aioe.org>
In reply to#79980
On 30/05/2021 12:18, Bonita Montero wrote:
> I've just checked:
>
> #include <iostream>
>
> using namespace std;
>
> int main()
> {
>     int i, j, k;
>     auto f = [&]() -> int
>     {
>         return i + j + k;
>     };
>     cout << sizeof f << endl;
> }
>
> Can anyone tell me whether the lambda has three pointers (24 bytes
> on 64 bit systems) instead of just one pointer inside the stack-frame,
> which could be an easy optimization ?

Yes it is 24 on 64 bit machine; Compiled with VS2019 using

> C:\Users\*******\Documents\cmdLine\cpp>cl /EHsc lambda01.cpp
> Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29915 for x64
> Copyright (C) Microsoft Corporation. All rights reserved.

German Manager helped by a German player won the Champions League for Chelsea ( a UK team) in Portugal!!! How wonderful it is.


[toc] | [prev] | [next] | [standalone]


#79993

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-30 19:34 +0200
Message-ID<s90ic4$hpk$1@dont-email.me>
In reply to#79992
> Yes it is 24 on 64 bit machine; Compiled with VS2019 using
>> C:\Users\*******\Documents\cmdLine\cpp>cl /EHsc lambda01.cpp

It isn't different with -Ox, but it could have been.

[toc] | [prev] | [next] | [standalone]


#79995

FromDavid Brown <david.brown@hesbynett.no>
Date2021-05-30 20:31 +0200
Message-ID<s90lmn$icr$1@dont-email.me>
In reply to#79980
On 30/05/2021 13:18, Bonita Montero wrote:
> I've just checked:
> 
> #include <iostream>
> 
> using namespace std;
> 
> int main()
> {
>     int i, j, k;
>     auto f = [&]() -> int
>     {
>         return i + j + k;
>     };
>     cout << sizeof f << endl;
> }
> 
> Can anyone tell me whether the lambda has three pointers (24 bytes
> on 64 bit systems) instead of just one pointer inside the stack-frame,
> which could be an easy optimization ?

The question doesn't really make sense.

When optimising, a compiler will not generate anything for any of the
variables or the lambda.

When looking at this kind of thing, I like to use the online compiler at
<https://godbolt.org> and look at the assembly.  This is easier if you
don't try to generate printed output:


int foo() {
    int i, j, k;

    auto f = [&]() {
        return i + j + k;
    };
    return sizeof(f);
}

gcc generates:

foo():
        movl    $24, %eax
        ret

So the compiler is trying to give you the size of storage it would need
in general for a lambda that took three references.  But since the
optimised lambda is entirely removed, it is not the actual size of "f"
in the optimised code.

AFAIK the standard doesn't say anything about what size lambdas should
be, or anything else about their types.  But I would guess that
compilers try to give consistent results for the sizeof of a lambda
regardless of the optimisation or details of the implementation.

[toc] | [prev] | [next] | [standalone]


#79996

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-30 20:46 +0200
Message-ID<s90mhf$2ha$1@dont-email.me>
In reply to#79995
> So the compiler is trying to give you the size of storage it would need
> in general for a lambda that took three references.  But since the
> optimised lambda is entirely removed, it is not the actual size of "f"
> in the optimised code.

The compiler could also give the size of an optimized lambda.

Consider this:

#include <iostream>
#include <functional>

using namespace std;

int main()
{
	int i = 123, j = 456, k = 789;
	auto f = [&]() -> int
	{
		return i + j + k;
	};
	function<int()> ff = f;
	function<int()> *volatile pFf = &ff;
	cout << sizeof f << " " << (*pFf)() << endl;
}

I pack f into a function<> and then I assign the address to a volatile
pointer to prevent any optimizations on calling the function-object.
So according to what you suggesst the compiler would have the chance
to optimize the three references - but it doesn't.

[toc] | [prev] | [next] | [standalone]


#79999

FromÖö Tiib <ootiib@hot.ee>
Date2021-05-30 12:26 -0700
Message-ID<bcf71774-0c95-4741-9d68-7f0b30ec584en@googlegroups.com>
In reply to#79996
On Sunday, 30 May 2021 at 21:46:22 UTC+3, Bonita Montero wrote:
> > So the compiler is trying to give you the size of storage it would need 
> > in general for a lambda that took three references. But since the 
> > optimised lambda is entirely removed, it is not the actual size of "f" 
> > in the optimised code.
> The compiler could also give the size of an optimized lambda. 
> 
> Consider this: 
> 
> #include <iostream> 
> #include <functional>
> using namespace std; 
> 
> int main() 
> {
> int i = 123, j = 456, k = 789;
> auto f = [&]() -> int 
> { 
> return i + j + k; 
> };
> function<int()> ff = f; 
> function<int()> *volatile pFf = &ff; 
> cout << sizeof f << " " << (*pFf)() << endl; 
> } 

Looks like horrible pile of garbage that still does nothing.

> I pack f into a function<> and then I assign the address to a volatile 
> pointer to prevent any optimizations on calling the function-object. 
> So according to what you suggesst the compiler would have the chance 
> to optimize the three references - but it doesn't.

If some optimization in some compiler of some feature is missing and
so your resulting program is slow then you should write less garbage
code that compiler can't optimize. Or you can take source code of 
compiler, implement the optimization you need and put up a pull
request.
 

[toc] | [prev] | [next] | [standalone]


#80009

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-31 06:16 +0200
Message-ID<s91nuk$e0p$1@dont-email.me>
In reply to#79999
You're so ultimately stupid.

[toc] | [prev] | [next] | [standalone]


#80024

FromMarcel Mueller <news.5.maazl@spamgourmet.org>
Date2021-05-31 18:33 +0200
Message-ID<s93348$efb$1@gwaiyur.mb-net.net>
In reply to#79980
Am 30.05.21 um 13:18 schrieb Bonita Montero:
> #include <iostream>
> 
> using namespace std;
> 
> int main()
> {
>      int i, j, k;
>      auto f = [&]() -> int
>      {
>          return i + j + k;
>      };
>      cout << sizeof f << endl;
> }
> 
> Can anyone tell me whether the lambda has three pointers (24 bytes
> on 64 bit systems) instead of just one pointer inside the stack-frame,

A generic function pointer typically take 3 machine size words to 
support all cases of polymorphism. Note that a lambda with closures is 
in fact equivalent to a class with a (virtual) interface function with 
the lambda signature. So we are talking about a /member function 
pointer/ in general. Due to multiple inheritance and implicit upcasts 
this is not simply a pointer to code.

> which could be an easy optimization ?

There is nothing you can do. The compiler on the other side is not 
required to allocate the storage unless it is really needed.


Marcel

[toc] | [prev] | [next] | [standalone]


#80025

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-31 18:50 +0200
Message-ID<s9344u$mqr$1@dont-email.me>
In reply to#80024
> A generic function pointer typically take 3 machine size words to 
> support all cases of polymorphism. Note that a lambda with closures is 
> in fact equivalent to a class with a (virtual) interface function with 
> the lambda signature. So we are talking about a /member function 
> pointer/ in general. Due to multiple inheritance and implicit upcasts 
> this is not simply a pointer to code.

The three pointers have a fixed relationship to each other so that the
compiler could store a single pointer somewhere inside the stackframe
and address the three variables as [reg+a], [reg+b] and [reg+c].

[toc] | [prev] | [next] | [standalone]


#80027

FromMarcel Mueller <news.5.maazl@spamgourmet.org>
Date2021-05-31 20:27 +0200
Message-ID<s939qj$sip$2@gwaiyur.mb-net.net>
In reply to#80025
Am 31.05.21 um 18:50 schrieb Bonita Montero:
[Lambda pointer]
> The three pointers have a fixed relationship to each other so that the
> compiler could store a single pointer somewhere inside the stackframe
> and address the three variables as [reg+a], [reg+b] and [reg+c].

No they have not. You may assign any other function pointer to the 
function type f later.


Marcel

[toc] | [prev] | [next] | [standalone]


#80031

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-06-01 06:14 +0200
Message-ID<s94c6n$kpf$1@dont-email.me>
In reply to#80027
>> The three pointers have a fixed relationship to each other so that the
>> compiler could store a single pointer somewhere inside the stackframe
>> and address the three variables as [reg+a], [reg+b] and [reg+c].

> No they have not. You may assign any other function pointer to the 
> function type f later.

Of course they have because the stack has a fixed layout. And even
more: you may put _no_ pointer inside the lambda-object since it has
fixed place inside the stack and you could address all other objects
at relative addresses to that address.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web