Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Puschie

Frischling

  • »Puschie« ist der Autor dieses Themas

Beiträge: 25

Wohnort: Sachsen-Anhalt

  • Private Nachricht senden

1

13.12.2011, 18:44

Funktionszeiger

Hey ich wollte mal gern wissen, in welcher Stellung Funktionszeiger zu Geschwindigkeit stehen, da die in C++ für Spieleprogrammierer nicht erwähnt wurden, dachte ich bisher, dass diese relativ unbedeutend sind. Aber da ich nun in meinen eigenem Projekt die Render funktionen fertig habe, und diese Pro Sekunde einige hundertmale aufgerufen werden, dachte ich mir, dass man mit Funktionszeiger die geschwindigkeit deutlich erhöhen könnte?
MFG Puschie

2

13.12.2011, 18:51

Geschwindigkeit und Flexibilität sind zwei konkurrierende Ziele.

Funktionszeier erhöhen die Flexibilität, so auch virtuelle Methoden, ...

8)

Gruß ...

Zitat

Ich bin nicht der Messias.
Ich sage, du bist es, Herr. Und ich muss es wissen, denn ich bin schon einigen gefolgt.

https://bitbucket.org/bwbg

3

13.12.2011, 18:58

Man benutzt doch Funktionszeiger nicht wegen der Performance. Viel mehr verwendet man diese als Callbacks. Aber auch als delegates kommen sie in Frage, wenn auch in der STL dafür Templates verwendet wurden.

Puschie

Frischling

  • »Puschie« ist der Autor dieses Themas

Beiträge: 25

Wohnort: Sachsen-Anhalt

  • Private Nachricht senden

4

13.12.2011, 20:05

Ok, vielen Dank für die schnelle Antwort
MFG Puschie

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

5

13.12.2011, 20:09

Einige hundert Funktionsaufrufe pro Sekunde sind von der Performance her denke ich fast zu vernachlässigen ;)

Wie hast du dir denn vorgestellt, dass man die Funktionszeiger zur Verbesserung der Performance einsetzen kann? So richtig sehe ich den Zusammenhang an der Stelle gerade nicht.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

6

13.12.2011, 20:34

Wenn überhaupt verlangsamen Funktionszeiger (im Gegensatz zu normalen Funktionsaufrufen) den Aufruf sogar minimal.
Aber auch dann spielt es für reale Anwendungsfälle überhaupt keine Rolle was du benutzt.
Das ist in etwa so sinnvoll, wie wenn du deinen Körper auf Aerodynamik optimieren willst, damit du schneller gehen kannst. Theoretisch funktioniert das auch, aber alleine der Gedanke das zu machen Zeitverschwendung im Sinne der Optimierung. ;)

Wenn dich allerdings interessiert was da genau passiert: lern Assembler und CPU Architektur und schau dir indirekte Funktionsaufrufe an. Dort wirst du dann sehen was ich mit meinem ersten Satz genau meinte.

7

18.12.2011, 14:26

Das hat mich jetzt mal etwas genauer interessiert. Hier mal ein Benchmark mit dem Ergebnis, dass sich bei 80mio. Durchläufen bei mir ungefähr ein Unterschied von 2 sec ergeben haben. Wenn einer Lust hat, kann er ja mal 1 mrd Durchläufe testen ;)

C-/C++-Quelltext

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <time.h>

using namespace std;

template<class TIter, class TFunc, class TValue>
int count_multiple(TIter begin, TIter end, TFunc equals, TValue compare) {
    int count = 0;
    while (begin != end) {
        if (equals(*begin++, compare))
            count++;
    }
    return count;
}

template<class TFunc, TFunc equals, class TIter, class TValue>
int count_multiple(TIter begin, TIter end, TValue compare) {
    int count = 0;
    while (begin != end) {
        if (equals(*begin++, compare))
            count++;
    }
    return count;
}

template<class T>
bool equals(T a, T b) {
    return a == b;
}

__int64 dummy(__int64 i) {
    return i/2L*i;
}

int main(int argc, char **argv) {
    __int64 REPETITION_COUNT = 80000000L; // 80 mio
    int array[] = { 1,1,1,2,3,4,5,6,7,8, 9,
                    1,1,1,2,3,4,5,6,7,8, 9,
                    1,1,1,2,3,4,5,6,7,8, 9,
                    1,1,1,2,3,4,5,6,7,8, 9,
                    1,1,1,2,3,4,5,6,7,8, 9 };
    int multiple_count;
    clock_t time_first = 0, time_second = 0;
    
    multiple_count = 0; 

    time_first = clock();
    for (__int64 i = 0; i < REPETITION_COUNT; i++) {
        multiple_count += count_multiple(array, array+(10*5-1), equals<int>, 1);
        multiple_count = dummy(multiple_count);
        // cout << multiple_count << endl;
    }
    time_first = clock() - time_first;

    multiple_count = 0;

    time_second = clock();
    for (__int64 i = 0; i < REPETITION_COUNT; i++) {
        multiple_count += count_multiple<bool (*)(int,int),equals>(array, array+(10*5-1), 1);
        multiple_count = dummy(multiple_count);
        // cout << multiple_count << endl;
    }
    time_second = clock() - time_second;

    cout << "With Pointer: " << time_first / CLOCKS_PER_SEC << endl
        << "Constant: " << time_second / CLOCKS_PER_SEC << endl;

    system("pause");

    return 0;
}

Ausgabe:

Quellcode

1
2
3
With Pointer: 13
Constant: 11
Drücken Sie eine beliebige Taste . . .

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

18.12.2011, 15:25

Wenn Du jetzt noch sicherstellst, dass beide Calls die selbe Anzahl an Parametern pushen müssen, dann wäre der Test vielleicht sogar aussagekräftig ;)
Es ist an der Stelle sogar fraglich, ob es der Compiler nicht sogar weg optimiert hat. Ohne jetzt böse wirken zu wollen, das Ergebnis zeigt zwar einen Trend, aber so richtig korrekt ist das eher nicht. Immerhin muss der ohne Pointer ja nur 3 Parameter übergeben, der andere 4.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

18.12.2011, 15:44

Hmm. Okay, hab den Test mit dieser Version wiederholt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
template<class TFunc, TFunc equals, class TIter, class TValue>
int count_multiple(TIter begin, TIter end, TValue compare, void *ptr) {
int count = 0;
while (begin != end) {
    if (equals(*begin++, compare))
        count++;
}
return count;
}
...
time_second = clock();
    for (__int64 i = 0; i < REPETITION_COUNT; i++) {
        multiple_count += count_multiple<bool (*)(int,int),equals>(array, array+(10*5-1), 1, (void*)0x928);
        multiple_count = dummy(multiple_count);
        // cout << multiple_count << endl;
    }
    time_second = clock() - time_second;
...

Hat aber das gleiche Ergebnis und da dürfte eigl. der Parameter nicht rausoptimiert werden, oder?

10

18.12.2011, 15:57

Einfach mal Optimierungen ausschalten, dann verschwindet sicher kein Parameter..

Werbeanzeige