[C++] Doorgeven pointer arrays

Pagina: 1
Acties:
  • 118 views sinds 30-01-2008
  • Reageer

  • Opi
  • Registratie: Maart 2002
  • Niet online
Ik probeer een array te updaten, maar de waarde die ik er in de functie in stop wordt er niet uitgehaald. Ik heb gekeken naar de pointers en nu ben ik erachter gekomen dat de output van pointer 1 (regel 28 van a.cpp) gelijk is aan de output van pointer 2 (regel 19 van ex_file.cxx), maar ongelijk aan die van pointer 3 (regel 21 van ex_file.cxx). Het probleem zit hem dus in regel 20 van ex_file.cxx. Ik weet alleen niet hoe ik dit probleem kan omzeilen, maar simpelweg wil ik er voor zorgen dat in regel 41 van a.cpp de inhoud van array_1 gelijk is aan de inhoud van matrix_1.

Mochten er onduidelijkheden zitten in de code of dingen die je qua codestructurering onlogisch lijken dan hoor ik graag opmerkingen. :)

File a.cpp:
C++:
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream.h>
#include <stdlib.h>
#include <fstream.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

#include "ex_file.cxx"
#include "ex_file.hxx"


void functie_1(double *array_1, int lengte)
{
    ex_file *controller;
    controller = new ex_file();

    controller->func_ex(array_1, lengte);

    cout << *array_1 << endl;   // 1
    
    return;
}

int main
{
    double *array_1;
    int lengte = 30;
    void functie_1(double *, int);
    
    array_1 = new double[lengte];
    functie_1(array_1, lengte);
    
    return 0;
}


File ex_file.cxx:
C++:
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "ex_file.hxx"
#include <math.h>
#include <time.h>
#include <stdlib.h> 

void ex_file::func_ex(double *matrix_1, int breedte)
{
    srand ( time(NULL) );
    
    cout <<  matrix_1 << endl;  // 2
    matrix_1 = new double[breedte];
    cout <<  matrix_1 << endl;  // 3
    
    for(i = 0; i < breedte; i++)
    {
        {   
            a = rand();
            matrix_1[i] = (2*a/RAND_MAX - 1.0);
        }
    }
    return; 
}

File ex_file.hxx:
C++:
10
11
12
13
14
15
16
17
18
19
#ifndef ex_file_hxx
#define ex_file_hxx

class ex_file
{
    int i, a;
    void func_ex(double *matrix_1, int breedte)
};

#endif

[ Voor 6% gewijzigd door Opi op 03-05-2004 18:54 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nogal wiedes

ex_file.cxx:
C++:
20
matrix_1 = new double[breedte]; 


waarom doe je dat? matrix_l krijgt dan een nieuwe waarde, logisch dat ie anders is dan de waarde die ie al had

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.


  • Opi
  • Registratie: Maart 2002
  • Niet online
.oisyn schreef op 03 mei 2004 @ 18:01:
Nogal wiedes

ex_file.cxx:
C++:
20
matrix_1 = new double[breedte]; 


waarom doe je dat? matrix_l krijgt dan een nieuwe waarde, logisch dat ie anders is dan de waarde die ie al had
De grootte ervan is afhankelijk van de grootte van array_1. Is het wel mogelijk dat de waarden die in matrix_1 staan doorgegeven worden naar array_1?

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 25-05 16:59

Robtimus

me Robtimus no like you

.oisyn schreef op 03 mei 2004 @ 18:01:
Nogal wiedes

ex_file.cxx:
C++:
20
matrix_1 = new double[breedte]; 


waarom doe je dat? matrix_l krijgt dan een nieuwe waarde, logisch dat ie anders is dan de waarde die ie al had
Idd. Je overschrijft de pointer gewoon (new alloceert een nieuw stuk geheugenruimte en wijst dat toe), de oude pointer is verdwenen, en de geheugenplek waar die naar verwees wordt zonder garbagecollector niet vrijgemaakt -> mem leak.

Je moet voor regel 37 in a.cpp je array al initialiseren, en dan gewoon doorgeven. Dat doe je al, sorry.

[ Voor 4% gewijzigd door Robtimus op 03-05-2004 18:08 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 25-05 16:59

Robtimus

me Robtimus no like you

OpifexMaximus schreef op 03 mei 2004 @ 18:05:
[...]

De grootte ervan is afhankelijk van de grootte van array_1. Is het wel mogelijk dat de waarden die in matrix_1 staan doorgegeven worden naar array_1?
Je geeft aan die functies een pointer naar je array door. Het schrijven naar / lezen van het array gebeurt dus in je oorspronkelijke idee; veranderingen in de functie zie je ook op het niveau van declareren. Zodra je die ene declaratie verwijdert zou het moeten werken.

[ Voor 7% gewijzigd door Robtimus op 03-05-2004 18:10 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
C++:
1
2
3
4
5
6
7
int main
{
    double *array_1;
    int lengte = 30;
    void functie_1(double *, int); 
    .....
}
Ik weet niet maar declareer je hier niet nested (lokale) functie ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 25-05 20:56
OpifexMaximus schreef op 03 mei 2004 @ 17:57:

File a.cpp:
C++:
21
void functie_1{double *array_1, int lengte}
Zijn dat daar accolades i.p.v. haakjes? Hoe krijg je dat ooit gecompileerd?

Verwijderd

OpifexMaximus schreef op 03 mei 2004 @ 17:57:
Mochten er onduidelijkheden zitten in de code of dingen die je qua codestructurering onlogisch lijken dan hoor ik graag opmerkingen. :)
Het ziet er naar uit dat je wel eens in Pascal en afentoe wat Java geprogrammeerd hebt, zou dat kunnen? ;)

Ik veronderstel dat je een functie wilt schrijven die een nieuw array van opgegeven lengte aanmaakt en vult met willekeurige gegevens; en dat array vervolgens in een andere functie bewerken? Laat ik dan een eenvoudig voorbeeld daarvan geven:

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
33
#include <stdlib.h>
#include <time.h>
#include <iostream.h>

double* functie_1(size_t lengte)
{
    double* returnwaarde= new double[lengte];    // Reserveer een stuk
    // geheugen, returnwaarde bevat nu het beginadres van dat stuk
    // geheugen

    for(size_t i= 0; i < lengte; ++i) {
        returnwaarde[i]= 2.0 * rand() / RAND_MAX - 1;
    }

    return returnwaarde;    // Retourneer het adres
}

int main()
{
    srand(time(NULL));    // De random generator seeden hoeft maar een maal

    size_t len= 30;
    double* array_1= functie_1(len);    // Zet het adres dat func_1
    // retourneert in array_1

    for(size_t i= 0; i < len; ++i) {    // Druk alle elementen van het array af
        cout << array_1[i] << '\n';
    }

    delete [] array_1;    // Geef het geheugengebied weer vrij

    return 0;    // Einde programma
}

Er valt nog wel wat aan te merken op deze code, maar het is een indicatie van de C(++) manier van doen.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Zal ik de aanmerkingen dan maar maken?
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
#include <cstdlib> // C++ standaard library headers hebben geen .h extensie
#include <ctime> 
#include <iostream> 
#include <vector>

std::vector<double> functie_1(size_t lengte) 
{ 
    std::vector<double> returnwaarde( lengte );    // Object

    for(size_t i = 0; i != lengte; ++i) { 
        returnwaarde[i] = 2.0 * rand() / RAND_MAX - 1; 
    } 

    return returnwaarde;    // Retourneer het object
} 

int main() 
{ 
    srand(time(NULL));    // De random generator seeden hoeft maar een maal 

    size_t len= 30; 
    std::vector<double> array_1 = functie_1(len);    // het geretourneerde object

    for(size_t i= 0; i < len; ++i) {    // Druk alle elementen van het array af 
        std::cout << array_1[i] << '\n'; 
    } 
    // Verder niks meer nodig
}

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

IceManX schreef op 03 mei 2004 @ 18:07:
[...]
Idd. Je overschrijft de pointer gewoon (new alloceert een nieuw stuk geheugenruimte en wijst dat toe), de oude pointer is verdwenen, en de geheugenplek waar die naar verwees wordt zonder garbagecollector niet vrijgemaakt -> mem leak.
Nee hoor, de pointer bestaat nog in de aanroepende functie, en de functie die die functie weer aanroept :)

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.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

farlane schreef op 03 mei 2004 @ 18:19:
[...]


Ik weet niet maar declareer je hier niet nested (lokale) functie ?
C/C++ kent geen nested functies. Het is een gewone legale functiedeclaratie
Soultaker schreef op 03 mei 2004 @ 18:39:
[...]

Zijn dat daar accolades i.p.v. haakjes? Hoe krijg je dat ooit gecompileerd?
Zie boven :)

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

MSalters schreef op 03 mei 2004 @ 19:03:
Zal ik de aanmerkingen dan maar maken?
Het gebruik van de STL leek me iets te hoog gegrepen omdat de TS zuiver in C-style met pointers goochelt (en naar mijn indruk niet helemaal de scoping van variabelen onder de knie heeft; niet als enige, overigens ;) ). Vandaar dat ik ook een expliciete return in main gebruikte, anders krijg je weer lastige vragen :)

edit:
Valt me trouwens tegen dat je er geen std::copy naar een std::ostream_iterator op los laat ;)

[ Voor 11% gewijzigd door Verwijderd op 03-05-2004 19:22 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Ej ja, ik probeerde het simpel te houden. Anders had ik ook wel een iterator meegegeven aan functie1; dat is wat toekomst vaster.

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


  • Opi
  • Registratie: Maart 2002
  • Niet online
Soultaker schreef op 03 mei 2004 @ 18:39:
[...]

Zijn dat daar accolades i.p.v. haakjes? Hoe krijg je dat ooit gecompileerd?
Ik heb het om proberen te schrijven naar code die relevant is voor het probleem. Schijnbaar heb ik iets over het hoofd gezien. Compileren lukt iig wel. :)
Verwijderd schreef op 03 mei 2004 @ 18:52:
[...]


Het ziet er naar uit dat je wel eens in Pascal en afentoe wat Java geprogrammeerd hebt, zou dat kunnen? ;)
Nee, sorry. :) Ik probeer het universeel en begrijpelijk te houden. Helaas niet helemaal gelukt. Volgende keer beter. :Y)
Ik veronderstel dat je een functie wilt schrijven die een nieuw array van opgegeven lengte aanmaakt en vult met willekeurige gegevens; en dat array vervolgens in een andere functie bewerken? Laat ik dan een eenvoudig voorbeeld daarvan geven:

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
33
#include <stdlib.h>
#include <time.h>
#include <iostream.h>

double* functie_1(size_t lengte)
{
    double* returnwaarde= new double[lengte];    // Reserveer een stuk
    // geheugen, returnwaarde bevat nu het beginadres van dat stuk
    // geheugen

    for(size_t i= 0; i < lengte; ++i) {
        returnwaarde[i]= 2.0 * rand() / RAND_MAX - 1;
    }

    return returnwaarde;    // Retourneer het adres
}

int main()
{
    srand(time(NULL));    // De random generator seeden hoeft maar een maal

    size_t len= 30;
    double* array_1= functie_1(len);    // Zet het adres dat func_1
    // retourneert in array_1

    for(size_t i= 0; i < len; ++i) {    // Druk alle elementen van het array af
        cout << array_1[i] << '\n';
    }

    delete [] array_1;    // Geef het geheugengebied weer vrij

    return 0;    // Einde programma
}

Er valt nog wel wat aan te merken op deze code, maar het is een indicatie van de C(++) manier van doen.
Op zich kan ik deze methode gebruiken, maar toch gebruik ik liever mijn huidige aanpak omdat ik meerdere variabelen/arrays wil initialiseren. Maar volgens mij is de door jou voorgestelde aanpak nog steeds te gebruiken of niet?

@ MSalters: ik probeer het voor mezelf begrijpelijk te houden en wil daarom zo min mogelijk libraries gebruiken. Desalniettemin bedankt voor je voorstel.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
@Opifex: Pointers zijn de snelste manier om het voor jezelf onbegrijpelijk te maken. Objecten raken niet kwijt. Domme pointers lekken als je even niet goed oplet.

In elk geval wil je waarschinlijk naar een OO oplossing toe, als je meerdere arrays wil initialiseren. Als die met elkaar verband houden, dan horen ze waarschijnlijk samen in een class.

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


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 25-05 16:59

Robtimus

me Robtimus no like you

.oisyn schreef op 03 mei 2004 @ 19:10:
[...]


Nee hoor, de pointer bestaat nog in de aanroepende functie, en de functie die die functie weer aanroept :)
Oepsie :o
Over het hoofd gezien ja. In die functie bestaat hij niet meer, daarbuiten nog wel ja.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
.oisyn schreef op 03 mei 2004 @ 19:11:
C/C++ kent geen nested functies. Het is een gewone legale functiedeclaratie
Hmmm was dat Java dan ? Anywayz, naar mijn smaak staat ie daar wel gek, temeer omdat het ding er vlak boven al gedefinieerd wordt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Opi
  • Registratie: Maart 2002
  • Niet online
MSalters schreef op 03 mei 2004 @ 20:29:
In elk geval wil je waarschinlijk naar een OO oplossing toe, als je meerdere arrays wil initialiseren. Als die met elkaar verband houden, dan horen ze waarschijnlijk samen in een class.
Kan je een voorbeeld geven van hoe ik dit het best kan aanpakken? Bijvoorbeeld Hoe kan ik dit in het geval van (bijvoorbeeld) een tweetal arrays doen? Mijn aanpak en de aanpak van mietje schieten hier volgens mij tekort. Toch wil ik graag mijn aanpak grotendeels blijven volgen (heb niet zo heel erg veel zin om alles weer aan te passen ;)).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Bedoel je soms pascal/delphi?
Anywayz, naar mijn smaak staat ie daar wel gek, temeer omdat het ding er vlak boven al gedefinieerd wordt.
Ja het was natuurlijk in dit geval niet nodig geweest, maar declaraties zijn prima mogelijk binnen function scope. De declaratie blijft dan ook alleen geldig binnen die scope. Hetzelfde geldt voor typedefs.

C++:
1
2
3
4
5
6
7
8
9
void func1 ()
{
    {
        void func2 (int);
        func2 (34); // ok
    }

    func2 (34); // error: "func2" niet gedefinieerd
}

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

OpifexMaximus schreef op 03 mei 2004 @ 23:27:
Kan je een voorbeeld geven van hoe ik dit het best kan aanpakken? Bijvoorbeeld Hoe kan ik dit in het geval van (bijvoorbeeld) een tweetal arrays doen? Mijn aanpak en de aanpak van mietje schieten hier volgens mij tekort. Toch wil ik graag mijn aanpak grotendeels blijven volgen (heb niet zo heel erg veel zin om alles weer aan te passen ;)).
Nee hoor, met mijn voorbeeld kun je ook meerdere arrays aanmaken, maar dat zijn dan allemaal individuele arrays gevuld met willekeurige waardes. Om het bij mijn vorige voorbeeld te houden kun je b.v. 2 arrays aanmaken met:
C++:
23
24
25
26
27
28
29
double* array_1= functie_1(len);
double* array_2= functie_1(len);

// Doe iets met array_1 en array_2

delete [] array_2;
delete [] array_1;

Wat MSalters bedoelt is dat als je 2 arrays hebt met waardes die op e.o.a. manier aan elkaar gecorreleerd zijn, je die arrays beter in een class kunt samenvatten:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdlib.h>
#include <time.h>
#include <iostream.h> 

class Random {
public:
    Random(size_t len)
        : lengte(len)
        , waardes(new double[len])
        , sommen(new double[len])
        {
            double som= 0.0;
            for(size_t i= 0; i < len; ++i) {
                double waarde= 2.0 * rand() / MAX_RAND - 1.0;
                som+= waarde;
                waardes[i]= waarde;
                sommen[i]= som;
           }
        }

    ~Random()
        {
            delete [] waardes;
            delete [] sommen;
        }

    size_t lengte;
    double* waardes;
    double* sommen;
};

int main()
{
    srand(time(NULL));

    Random rnd(30);    // Creeer een object met 30 waardes en 30 sommen
    // we roepen hier Random::Random(size_t) aan.

    for(size_t i= 0; i < rnd.lengte; ++i) {
        cout << "Waarde: " << rnd.waardes[i]
             << " partieele som: " << rnd.sommen[i]  << '\n';
    }

    // Het rnd object ruimt zijn eigen arrays op als het ophoudt te bestaan
    // door Random::~Random() aan te roepen.
}

[ Voor 10% gewijzigd door Verwijderd op 04-05-2004 00:27 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
OpifexMaximus schreef op 03 mei 2004 @ 23:27:
[...]

Kan je een voorbeeld geven van hoe ik dit het best kan aanpakken? Bijvoorbeeld Hoe kan ik dit in het geval van (bijvoorbeeld) een tweetal arrays doen? Mijn aanpak en de aanpak van mietje schieten hier volgens mij tekort. Toch wil ik graag mijn aanpak grotendeels blijven volgen (heb niet zo heel erg veel zin om alles weer aan te passen ;)).
Wat kleine dingetjes: de .cxx include je niet. Die geef je mee aan de linker, en die knoopt alles aan elkaar.
Je class ex_file heeft geen zinnige data of members. De twee variabelen hoeven niet tussen function calls bewaard te worden. Zet ze dus gewoon op de stack binnen de functie.
Als je twee arrays hebt die een verband hebben, dan moeten die wel samen in een class. De constructor van die class moet dan ervoor zorgen dat dat verband gaat gelden, en die moet dus de arrays vullen. Alle andere class methods houden dan dat verband in stand.
^^ zoiets ja

[ Voor 3% gewijzigd door MSalters op 04-05-2004 00:32 ]

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Wat aanmerkingen daarop: Die member variabelen zouden dus echt private moeten zijn. Je wil namelijk een public method getData(int index) hebben, en een getSum(int index). Hoe getSum wordt geimplementeerd hoeft de rest van de wereld niet te weten. Er zijn namelijk drie zinnige simpele implementaties(*), en die keus is iets wat je wil afschermen.

(*) In de constructor, bij de eerste call, of geen tweede array en bij elke call uitrekenen

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


  • Opi
  • Registratie: Maart 2002
  • Niet online
Bedankt voor de informatie! :)

Ik ben nu aan het kijken hoe ik de .cxx file het best om kan zetten naar een class. Is het mogelijk om in het voorbeeld van mietje de inhoud van rnd.waardes te veranderen na regel 36?

Verwijderd

OpifexMaximus schreef op 04 mei 2004 @ 13:32:
Bedankt voor de informatie! :)

Ik ben nu aan het kijken hoe ik de .cxx file het best om kan zetten naar een class. Is het mogelijk om in het voorbeeld van mietje de inhoud van rnd.waardes te veranderen na regel 36?
Ja dat is mogelijk, maar in de huidige opzet geen goed idee. Een van de basisprincipes van object-georienteerd programmeren is dat je je objecten consistent moet houden; als je zomaar rnd.waardes gaat zitten veranderen klopt rnd.sommen niet meer en is het rnd object inconsistent. De "nette" manier om dit op te lossen is een method (functie) aan class Random toe te voegen die het object consistent houdt.
C++:
27
28
29
30
31
32
33
34
    void zet_waarde(int index, double nieuwe_waarde)
        {
            double verschil= nieuwe_waarde - waardes[index];
            waardes[index]= nieuwe_waarde;
            for(; index < static_cast<int>(lengte); ++index) {
                sommen[index]+= verschil;
            }
        }

Zo gebruiken:
C++:
39
40
    rnd.zet_waarde(4, 0.12345);    // Verandert de 5e waarde in 0.12345 en
    // update de sommen

[ Voor 6% gewijzigd door Verwijderd op 04-05-2004 16:32 . Reden: typo ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

mierenneukmodus:
het is natuurlijk efficienter om die sommen on-demand te updaten, en niet bij het zetten van iedere waarde ;)

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.


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 110% gewijzigd door Eelis op 18-02-2015 19:34 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je bent natuurlijk stom als je niet gewoon een simpel vlaggetje bijhoudt

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.


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 99% gewijzigd door Eelis op 18-02-2015 19:34 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het testen van dat ene vlaggetje (je hoeft er maar 1 bij te houden) kost niets vergeleken met de functioncall zelf, dat merk je echt niet

.edit: oh wacht, ik ga hier misschien ten onrechte vanuit dat de array zelf ook private is en dat daar dus een functie voor is, zoals het hoort

[ Voor 35% gewijzigd door .oisyn op 04-05-2004 20:09 ]

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.


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 104% gewijzigd door Eelis op 18-02-2015 19:34 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

In dat geval zal branchprediction je wel helpen

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.


  • Eelis
  • Registratie: Januari 2003
  • Laatst online: 21-02-2015
.

[ Voor 99% gewijzigd door Eelis op 18-02-2015 19:34 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
De pipeline van een moderne CPu kan maar een ding doen. Bij een branch moet er gegokt worden. Wordt er fout gegokt, dan is de CPU daarna 10 tot 20 instructies aan het wachten. Naief (50%) zou dat dus gemiddeld 5-10 instructies zijn. Een goede prediction (95% tegenwoordig) reduceert de gemiddelde kosten van een branch prediction dus tot ~1 instructie.

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

idd, en aangezien je steeds dezelfde waarde controleert, zal hij bij elke controle sowieso al in de L1 cache staan en weet de CPU dat ie nog onveranderd is. Hij zal in dat geval ook wel goed "gokken".

Wat ik me overigens afvraag, hangt die prediction ook af van de code zelf? Ik weet niet precies hoe de CPU er mee omspringt, maar ik neem aan dat ie een één of andere heuristiek volgt, en dat hij de vorige uitkomst(en) dan ook ergens in de instruction cache zet. En als dat zo is heb je er natuurlijk weinig aan als de functie niet inline is en de compare overal in je code weer opduikt (als het dus niet in een loopje staat oid).

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

.oisyn schreef op 04 mei 2004 @ 19:57:
Je bent natuurlijk stom als je niet gewoon een simpel vlaggetje bijhoudt
Ff een tikkie terug :)

Ik zou geen simpele vlag bijhouden, maar de laagste index van de gewijzigde waardes. Op die manier hoef je alleen een deel van de sommen opnieuw te genereren op het moment dat een som met een grotere (of gelijke) index moet worden gelezen (het deel van die laagste index tot en met die grotere index moet opnieuw gegenereerd worden, waarna je de laagste index op de grotere index + 1 zet).

Wat voor gevolgen dat voor de caching/branch prediction heeft is me niet helemaal duidelijk, maar volgens mij win je de verliezen makkelijk terug omdat je veel minder floating point operaties hoeft te doen.

[ Voor 5% gewijzigd door Verwijderd op 05-05-2004 02:46 . Reden: gelijke toch maar toegevoegd, zinnen lopen voor geen meter ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 05 mei 2004 @ 02:19:
[...]


Ff een tikkie terug :)

Ik zou geen simpele vlag bijhouden, maar de laagste index van de gewijzigde waardes.
mee eens :)
Wat voor gevolgen dat voor de caching/branch prediction heeft is me niet helemaal duidelijk, maar volgens mij win je de verliezen makkelijk terug omdat je veel minder floating point operaties hoeft te doen.
Dat denk ik idd ook, maar even totaal afgezien van dat: een branch mis-prediction is over het algemeen wel duurder dan enkele (simpele) floating point operaties.

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: 09-04 22:08
.oisyn schreef op 04 mei 2004 @ 22:06:
idd, en aangezien je steeds dezelfde waarde controleert, zal hij bij elke controle sowieso al in de L1 cache staan en weet de CPU dat ie nog onveranderd is. Hij zal in dat geval ook wel goed "gokken".

Wat ik me overigens afvraag, hangt die prediction ook af van de code zelf? Ik weet niet precies hoe de CPU er mee omspringt, maar ik neem aan dat ie een één of andere heuristiek volgt, en dat hij de vorige uitkomst(en) dan ook ergens in de instruction cache zet. En als dat zo is heb je er natuurlijk weinig aan als de functie niet inline is en de compare overal in je code weer opduikt (als het dus niet in een loopje staat oid).
offtopic:
Sorry van je topic Opi

Een moderne branch predictor houdt per branch instruction address statistieken bij. Dit kan bijvoorbeeld twee bits zijn (0-3). Elke keer dat de branch wordt genomen wordt de counter verhoogd (tenzij al 3), elke keer dat ie niet wordt genomen wrodt de counter verlaagd. Het voordeel van 2 bits is dat bij een herhaalde loop met 10 iteraties alleen de 11e test wordt gemist (voorspelling is doorgaan met loop), maar dat de eerste test van de volgende loop weer goed voorspeld wordt.

Inlinen lijkt negatief, maar kan juist heel positief zijn. Stel dat operator==(int,int) niet inlined zou zijn. Dan wordt voor alle integer vergelijkingen een enkele statistiek bijgehouden, dus ook de test if(argc==1) aan het begin van main().

[ Voor 2% gewijzigd door MSalters op 05-05-2004 16:51 . Reden: Niet tegelijk in comp.lang.c++.moderated posten |:( ]

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-05 23:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ah ok, helder, bedankt :)
offtopic:
groeten onder je post? ;)

[ Voor 45% gewijzigd door .oisyn op 05-05-2004 14:03 ]

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.

Pagina: 1