Return Valule Optimization in C++11

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Return Valule Optimization in C++11

Post by viorel2005 » 30 Oct 2013, 08:26

Buna ziua!

Avem codul:

Code: Select all

struct Point2D
{
double x;
double y;
};

Point2D *pPts=new Point2D[10000*10000];

Pana in C++11 nu puteam o functie de tipul:

Code: Select all

const Point2D& Aduna(const Point2D& p1, const Point2D& p2)
{
     Point2D p3;
     p3.x=p1.x+p2.x;
     p3.y=p1.y+p2.y;
    return p3;
}
Cum as putea scrie functia Aduna folosind C++11. Compilatorul folosid este intel XE 13, ultima versiune.
Deoarece am foarte multe Point2D(program de simulare 2D) nu pot aduga functii membre structurii Point2D sau sa folosesc
functii friend.


Multumesc anticipat.



User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Return Valule Optimization in C++11

Post by Silviu Ardelean » 30 Oct 2013, 17:13

Functia ta Aduna() are o mare hiba: intorce referinta la un obiect temporar care tocmai a pierdut scopul in momentul folosirii(asignarii) Aduna()!
Deci, daca pastrezi variabila locala pentru a intoarce rezultatul atunci ai nevoie de copiere sau move semantics (optim, cel putin teoretic - am dubii ca avand tipuri de date numerice pe modul release se simte o diferenta semnificativa).
Iar ca sa poti beneficia de move semantics din C++11 ai nevoie sa implementezi move constructor si move operator pe structura ta. Ti-ar fi util sa folosesti containerele din STL gen std::vector (containere ce folosesc move semantics) versus old classic C array declarat mai sus.

florin_b
Junior
Junior
Posts: 8
Joined: 10 Jun 2013, 10:38
Judet: Bucureşti

Re: Return Valule Optimization in C++11

Post by florin_b » 30 Oct 2013, 20:39

Am auzit si eu de move semantics, insa nu prea am aprofundat. Deocamdata incerc sa invat bine C++ fara chestiile complicate adaugate in C++11! :yes:

Totusi, in cazul de fata sunt curios cum s-ar implementa move semantics pentru structura aia. Cum ar putea duce la cod mai eficient fata de un copy constructor, daca corectezi codul sa returneze un Point2D, in loc de o referinta la un obiect de pe stiva?

viorel, poate nu stiu eu C++11, dar in C++ "traditional" returnezi valoarea direct, sau pasezi o referinta la un Point2D care va tine rezultatul:

Code: Select all

Point2D Aduna(const Point2D& p1, const Point2D& p2)
{
     Point2D p3;
     p3.x=p1.x+p2.x;
     p3.y=p1.y+p2.y;
    return p3;
}

// sau:

void Aduna(Point2D& suma, const Point2D& p1, const Point2D& p2)
{
     suma.x=p1.x+p2.x;
     suma.y=p1.y+p2.y;
}
Ce ai vrea sa faci cu functiile membru sau friend, si oricum, de ce ar fi ele o problema atunci cand ai multe puncte?

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Return Valule Optimization in C++11

Post by bu7ch3r » 30 Oct 2013, 21:28

Bravo florin_b!
Cu stima,
Lupu Claudiu

viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Re: Return Valule Optimization in C++11

Post by viorel2005 » 30 Oct 2013, 21:31

Silviu Ardelean wrote:Functia ta Aduna() are o mare hiba: intorce referinta la un obiect temporar care tocmai a pierdut scopul in momentul folosirii(asignarii) Aduna()!
Deci, daca pastrezi variabila locala pentru a intoarce rezultatul atunci ai nevoie de copiere sau move semantics (optim, cel putin teoretic - am dubii ca avand tipuri de date numerice pe modul release se simte o diferenta semnificativa).
Iar ca sa poti beneficia de move semantics din C++11 ai nevoie sa implementezi move constructor si move operator pe structura ta. Ti-ar fi util sa folosesti containerele din STL gen std::vector (containere ce folosesc move semantics) versus old classic C array declarat mai sus.
Deoarece am de efectuat multe calcule numerice(ex. inmultire de matrici), iar numarul de puncte este foarte mare, am nevoie ca sizeof(Point2D) sa fie minim din considerente de spatiu de memorie.
Cu cat adaug mai multe functii la structura Poin2D cu atat sizeof(Poin2D) devine mai mare.
Presupunand ca "ar fi fost legal" sa scriu urmatorul cod:

Code: Select all

const Point2D& Aduna(const Point2D& p1, const Point2D& p2)
{
     Point2D p3;
     p3.x=p1.x+p2.x;
     p3.y=p1.y+p2.y;
    return p3;
}

atunci ca timp de executie ar fi fost egal cu:

Code: Select all

void Aduna(const Point2D& p1, const Point2D& p2, const Point2D&  p3)
{
     p3.x=p1.x+p2.x;
     p3.y=p1.y+p2.y;
 
}
adica solutia lui florin_b. Iar aceasta ultima solutie se poate numi RVO?

florin_b
Junior
Junior
Posts: 8
Joined: 10 Jun 2013, 10:38
Judet: Bucureşti

Re: Return Valule Optimization in C++11

Post by florin_b » 30 Oct 2013, 21:58

Stai, de ce ar creste dimensiunea structurii cand ii adaugi metode?

Hai ca m-ai facut curios: ce vrei sa simulezi acolo? :ugeek:

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Return Valule Optimization in C++11

Post by bu7ch3r » 30 Oct 2013, 22:04

NU
Cu stima,
Lupu Claudiu

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Return Valule Optimization in C++11

Post by bu7ch3r » 30 Oct 2013, 22:06

@florin_b ... creste creste, e vorba de cache line sau icache, nu?
Cu stima,
Lupu Claudiu

florin_b
Junior
Junior
Posts: 8
Joined: 10 Jun 2013, 10:38
Judet: Bucureşti

Re: Return Valule Optimization in C++11

Post by florin_b » 30 Oct 2013, 22:14

Unde e vorba? El a zis ca daca pui metode in Point2D, sizeof(Point2D) creste. Nu stiu de ce a zis asta, in loc sa incerce si sa vada ca nu-i asa. Ca doar d-aia are compilator (si nu orice compilator!), sa compileze lucruri cu el si sa le ruleze. :mrgreen: :thumbup:

Totusi, cu move semantics imi explica si mie cineva? Ca de pe internet nu m-am lamurit cum s-ar aplica aici. :?:

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Return Valule Optimization in C++11

Post by bu7ch3r » 30 Oct 2013, 22:25

Cine zice ala explica....

Eu atat zic: std::move = CAST
Cu stima,
Lupu Claudiu

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Return Valule Optimization in C++11

Post by Silviu Ardelean » 30 Oct 2013, 22:26

florin_b wrote:Totusi, in cazul de fata sunt curios cum s-ar implementa move semantics pentru structura aia. Cum ar putea duce la cod mai eficient fata de un copy constructor, daca corectezi codul sa returneze un Point2D, in loc de o referinta la un obiect de pe stiva?
Dupa cum se stie sau ar trebui... copy constructorul e necesar a fi implementat explicit cand avem pointeri ca atribute si/sau obiecte polimorfice... in rest, cu tipuri de baza numerice are compilatorul grija sa-l genereze in spate (cu atat mai putin in cazul move constructor si move assigned operator).
Imo, move semantics in cazul asta cu aceea structura n-aduce nici o optimizare... doar bucuria de-a folosi un feature de limbaj nou. :) Deci solutiile propuse de tine cu copiere sau ceea cu referinta sunt mai mult decat satisfacatoare.
viorel2005 wrote: Deoarece am de efectuat multe calcule numerice(ex. inmultire de matrici), iar numarul de puncte este foarte mare, am nevoie ca sizeof(Point2D) sa fie minim din considerente de spatiu de memorie.
Solutia nu e sa scri functii ce intorc pointeri sau referinte la obiecte temporare/locale!
viorel2005 wrote:
Presupunand ca "ar fi fost legal" sa scriu urmatorul cod:

Code: Select all

const Point2D& Aduna(const Point2D& p1, const Point2D& p2)
{
     Point2D p3;
     p3.x=p1.x+p2.x;
     p3.y=p1.y+p2.y;
    return p3;
}
Tocmai ti-am spus ca NU e "legal" si cred ca copilatorul ti-a dat peste degete dar tu nu ne crezi! :)
viorel2005 wrote: Cu cat adaug mai multe functii la structura Poin2D cu atat sizeof(Poin2D) devine mai mare.
Ce are de-a face functia Aduna() cu continutul structurii tale atat timp cat nu e membra a structurii?
Daca tot vrei sa ai o astfel de adunare, de ce nu folosesti un membru static al structurii Point2D sau ceva de genul:

Code: Select all

struct Point2D
{
  Point2D(double _x, double _y)	// just for nicer initialization
	  : x(_x), y(_y)
  {
  }

  double x;
  double y;
};

class FooCompute {

  public:
	  static Point2D Aduna(const Point2D& p1, const Point2D& p2) {
		 p3.x = p1.x + p2.x;
		 p3.y = p1.y + p2.y;
	 
		 return p3;
	  }
  
  private:
	   static Point2D p3;
};

Point2D FooCompute::p3(0.0f, 0.0f);
bu7ch3r wrote:NU
Why not?! :mrgreen:
Last edited by Silviu Ardelean on 31 Oct 2013, 22:48, edited 1 time in total.

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Return Valule Optimization in C++11

Post by bu7ch3r » 30 Oct 2013, 22:39

Am zis "NU" la: "Aceasta ultima solutie se poate numi RVO"... ultima solutie era: void Aduna(const ref obiect, cosnt ref obiect, const ref obiect) --- ASTA NU E RVO...RVO e RVO.

Ar trebui sa clarificam ce e aia RVO ca sa nu ne batem degeaba in C++11-isme...

Cei din primul rand(florin_b), n-au voie sa raspunda...(decat daca vor)
Cu stima,
Lupu Claudiu

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Return Valule Optimization in C++11

Post by Silviu Ardelean » 30 Oct 2013, 22:55

bu7ch3r wrote:Am zis "NU" la: "Aceasta ultima solutie se poate numi RVO"...
Ma scuzati! Bateam in alta directie... :)

viorel2005
Membru
Membru
Posts: 208
Joined: 24 May 2008, 09:41

Re: Return Valule Optimization in C++11

Post by viorel2005 » 31 Oct 2013, 00:41

Multumesc pentru raspunsuri. Functiile matematice vor constitui o librarie de tip C. Peste ea va fi creata un wrapper in C++.
Din acest motiv nu pot folosi sts::vector si constructori. Design-ul va fi asemanator cu libraria BLAS implementata
de Intel in Intel Math-Kernel Library, iar compilatorul va fi Intel C++ Compiler ultima versiune.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Return Valule Optimization in C++11

Post by Ovidiu Cucu » 31 Oct 2013, 16:48

Am si eu cateva NU-uri.
Unele deja s-au spus, insa le repet pentru ca observ ca nu se prea tine cont de ele. :)
  1. In C NU exista referinte, deci exemplul dat e C++ NU C.
  2. In C NU exista "move semantics", deci NU prea are rost sa discutam despre asta in contextul dat.
  3. NU este adevarat ca pana la C++11 nu se puteau scrie functii de genul

    Code: Select all

    CFoo& f()
    {
        CFoo foo;
        // ...
        return foo; 
    };
    Ba poti dar NU e bine. Un compilator cu scaun la cap iti da un warning pe care-i bine sa NU-l ignori.
  4. Functiile membre (mai putin cele virtuale) NU contribuie la size-ul obiectelor.
  5. Functiile friend nici macar NU-s functii membre; cu atat mai mult NU incurca.
  6. La cate optimizari face azi un compilator, NU e garantat ca un program scris in C iese intotdeauna mai mic si mai fast decat unul similar scris in C++.
Si un sfat fara "NU": Fa totul cap-coada in C++ si lasa carcaleti gen "C cu wrapper C++ peste". Altfel s-ar putea sa te doara capul... ;)

Post Reply