Toon posts:

[C++] Visual C++ Optimizations

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb het probleem pas eigenlijk gespot wanneer ik naar release mode ging in C++

Maar nu is het zo dat ik heb uitgevonden dat inline moeten gedisabled worden, anders werkt mijn hele programma niet meer... Maar waarom? Enig idee hoe dit op te lossen? (want inline is toch groter, maar sneller niet?)

Verwijderd

Inlining zou toch geen effect op de correctheid van je programma mogen hebben??

  • whoami
  • Registratie: December 2000
  • Laatst online: 10:17
Ik vraag me ook af waarom je programma niet meer werkt, als je inline gebruikt?

inline is sneller omdat de code vd functie die je dan aanroept ahw in je code gezet wordt, ipv een call te doen naar die functie. Vandaar dat het dus sneller is.
Het zou idd geen effect mogen hebben op de goede werking van je prgramma.

https://fgheysels.github.io/


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

maw, je code bugt
whoami schreef op 22 mei 2003 @ 09:04:
Ik vraag me ook af waarom je programma niet meer werkt, als je inline gebruikt?

inline is sneller omdat de code vd functie die je dan aanroept ahw in je code gezet wordt, ipv een call te doen naar die functie. Vandaar dat het dus sneller is.
Het zou idd geen effect mogen hebben op de goede werking van je prgramma.
het wegwerken van de call zelf is niet zozeer wat het sneller maakt (ja uiteraard is het iets sneller, er zijn een paar instructies minder, maar dat is verwaarloosbaar ;)). Omdat de code niet meer in een aparte functie staat, kan hij geintegreerd worden in de aanroepende functie, waardoor nog veel betere optimalisaties mogelijk zijn. Bovendien "weet" de compiler op zo'n moment wat er in de aangeroepen functie gebeurd, waardoor de locale state (zoals locale variabelen die in registers staan) niet meer hoeft te worden opgeslagen in het geheugen

[ Voor 97% gewijzigd door .oisyn op 22-05-2003 10:35 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Mja :)
dat had ik door :p

Maar hoe kan ik nu weten WAAR die juist bugt? :S

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

door even zo'n inline functie te posten en hoe je 'm aanroept, misschien kunnen wij dan zien wat er mis is :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
.oisyn schreef op 22 mei 2003 @ 10:28:
het wegwerken van de call zelf is niet zozeer wat het sneller maakt (ja uiteraard is het iets sneller, er zijn een paar instructies minder, maar dat is verwaarloosbaar ;)).
Toch wel. Je bent namelijk een jump kwijt, dat vindt de pipeline leuk. Bovendien verklein je daar de kans op een page fault en kan de code kleiner worden, als de geinline-de code kleiner is dan de functiecall prolog/epilog.

De kans op een pagefault in een ander stuk van je programma kan hierdoor stijgen, maar dat is een tradeoff keus waar je de goede programmeurs aan kunt herkennen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
.oisyn schreef op 22 May 2003 @ 21:39:
door even zo'n inline functie te posten en hoe je 'm aanroept, misschien kunnen wij dan zien wat er mis is :)
AL mijn inline functies :S ? :S
ik schat dat dat toch wel een klein 20kb code is al tesaam (enkel inlines hé)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

MSalters schreef op 22 May 2003 @ 22:17:
[...]

Toch wel. Je bent namelijk een jump kwijt, dat vindt de pipeline leuk. Bovendien verklein je daar de kans op een page fault en kan de code kleiner worden, als de geinline-de code kleiner is dan de functiecall prolog/epilog.

De kans op een pagefault in een ander stuk van je programma kan hierdoor stijgen, maar dat is een tradeoff keus waar je de goede programmeurs aan kunt herkennen.
Aan die pagefaults heb je idd een punt, daar had ik even niet gedacht. Maar aan de andere kant komt een pagefault bij code tegenwoordig zo goed als niet voor. Over het algemeen is er geheugen zat zodat alle code van het programma zich ten alle tijden in het geheugen kan bevinden.

Wat die pipeline betreft: ik denk dat dat verwaarloosbaar is in vergelijking met de code die _in_ de functie zit en geoptimaliseert kan worden. Ik heb bijvoorbeeld een vector en matrix library waar ik operator overloading toepas. Vroeger was ik daar niet zo'n voorstander van, want dat bracht onnodige temporaries met zich mee waardoor er bijvoorbeeld bij een matrix vermenigvuldiging heen en weer gekopieerd werd. Tegenwoordig doe ik dat met inlining en creatief template gebruik, en wordt de berekening op het moment van de assignment uitgevoerd, en temporaries dus volledig weggeoptimaliseerd. En dat is de kracht van inlining imho

Voorbeeld (even uit mijn hoofd):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// methode 1
struct matrix
{
    float data[4][4];

    matrix operator * (const matrix & m) const
    {
        matrix r;
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                r.data[i][j] = data[i][0] * m.data[0][j];
                for (int k = 1; k < 4; k++)
                    r.data[i][j] += data[i][k] * m.data[k][j];
            }
        }
        return r;
    }
};

void func ()
{
    matrix a, b, c;
    // ...
    c = a * b;
}


(Stel even voor dat deze functie niet geinlined wordt, en dat er een operator = () is die met een for-lusje alles overzet)
In het ergste geval worden er dus 2 temporaries aangemaakt. Ten eerste die locale variabele r, en ten tweede een temporary waar het resultaat van r in komt te staan, die vervolgens aan c toegekend wordt


Een andere oplossing is zo (ik gebruik even geen templates, maar in mijn code is dat wel het geval. Daar wordt het aantal rijen en kolommen en het type per element ook met template argumenten bepaald)
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct matrix;

struct matrix_mul
{
    const matrix & l;
    const matrix & r;
    matrix_mul (const matrix & lhs, const matrix & rhs) : l (lhs), r (rhs) { }
};

struct matrix
{
    float data[4][4];

    inline matrix_mul operator * (const matrix & m) const
    {
        return matrix_mul (*this, m);
    }

    inline matrix & operator = (const matrix_mul & m)
    {
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                data[i][j] = m.l.data[i][0] * m.r.data[0][j];
                for (int k = 1; k < 4; k++)
                    data[i][j] += m.l.data[i][k] * m.r.data[k][j];
            }
        }
        return *this;
    }
};


De enige temporary is hier een matrix_mul structure, die gewoon weggeoptimaliseerd wordt door inlining, met als gevolg dat die operator = eigenlijk direct op de argumenten van de operator * werkt. De pipeline stall die weggewerkt wordt is mooi meegenomen, maar is in principe verwaarloosbaar

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
mja, dat had ik zo wel ongeveer door...
Maar waarom zou hij dat bij mij dan doen?

Ik heb ook al geprobeerd te debuggen maar op één of andere manier werkt het dan altijd... Dunno waarom :S

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 24 mei 2003 @ 09:48:
mja, dat had ik zo wel ongeveer door...
Maar waarom zou hij dat bij mij dan doen?

Ik heb ook al geprobeerd te debuggen maar op één of andere manier werkt het dan altijd... Dunno waarom :S
Je werkt niet toevallig multithreaded? Zo ja, dat verklaart waarom inlining resultaten verandert (timing, race conditions), en debuggen is altijd per thread dus dan knallen synchronizatieproblemen ook niet.

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
De standaard VC6/7 debug mode schakelt inlining uit. Daar is een praktische reden voor: Als je een breakpoint in functie f zet, dan zou de compiler anders op alle plekken waar f aangeroepen wordt die breakpoint er in moeten frotten.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 24 May 2003 @ 22:57:
De standaard VC6/7 debug mode schakelt inlining uit. Daar is een praktische reden voor: Als je een breakpoint in functie f zet, dan zou de compiler anders op alle plekken waar f aangeroepen wordt die breakpoint er in moeten frotten.
Zoals ik het begreep had ie de inlining juist expliciet aan gezet... :?

Professionele website nodig?


Verwijderd

Topicstarter
In release ja, in debug alles standaard laten staan. En ik werk niet multithreaded (toch niet in de functie die ik wil checken)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

De vraag is of ie multithreaded gebruikt wordt, niet of ie zelf threadjes jongt.

Professionele website nodig?


Verwijderd

Topicstarter
Mmmmmm, hoe is dat zichtbaar? Normaal werk ik single threaded

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Je weet toch wel of je die functie vanuit meerdere threads aanroept? Zo ja kun je synchronizatieproblemen hebben. Als je nergens multithreaded werkt is die mogelijkheid redelijkerwijs uit te sluiten :)

Professionele website nodig?

Pagina: 1