Was ist rechnerisch schneller? simple formel



  • hmm, das ist mir grad auch aufgefallen. Naja, ich sagte ja, das das Ergebnis nicht räpresentativ ist. => Machts besser 😉



  • MStimer mt;// Hier fav timer
        mt.start();
        int i=2;
      //  _asm{int 3}
        for(unsigned int j=0;j<100000000;++j)
          i=(i*i)/i;
        mt.end();
        mt.start();
        for(unsigned int k=0;k<100000000;++k)
          i=(i<<1)/i;
        mt.end();
        cout<<endl<<i<<endl;// gegen optimierung
    

    output
    3.8352
    3.108



  • MaSTaH schrieb:

    @randa: Weißt du was? Glaub doch was du willst. Mir ist das langsam echt zu blöd hier. Nichts als Wischiwaschi bekommt man von dir zu hören.

    Das glaubte ich von dir zu hören.

    Du jonglierst hier nur mit Zahlen ohne Sinn und Verstand

    Diejenigen, die das gemacht haben, waren bisher du und Maschi, mit den Takten und den Shifts und bla.

    Fakten auf den Tisch zu bringen.

    Das habe ich getan.

    Wer soll dir das bitte abkaufen?

    Den Test hab ich heute Morgen gemacht, lang wieder gelöscht. Wenn du es mir nicht glaubst, mir egal. Meine Rechnungen hab ich ja offengelegt, mehr Source gibts gar nicht...Du willst dich wirklich nur wichtigmachen.

    In einem kleinen Konsolenprogramm wirst du den Effekt nämlich nicht so leicht bemerken können.

    Was du bisher nicht verstanden hast, ist, das es nicht drauf ankommt, ob du 10, 14, 20, oder 30% Performance gewinnst. Warum? Lies meinen ersten post nach dem close. Es nützt deiner Glaubwürdigkeit nichts, darauf rumzureiten, da ich noch eineiges mehr geschrieben hab. Aber du hast eher was gefunden, wo ich was nicht ganz korrekt gemacht hab, und so kannst wohl auch glücklich sein.
    Dein Post, Mastah, hatte gar keine Aussagekraft, außer zu flamen.

    Wenn sonst nichts mehr vernünftiges kommt, steig ich hier aus. Ich finde es schade, das die Kritiker nicht versuchen, die normale Diskussion fortzuführen, die ich anzufangen versuchte. => Mir wurscht, jeder optimiert selber.

    Ciao.



  • randa schrieb:

    Meine Rechnungen hab ich ja offengelegt, mehr Source gibts gar nicht...Du willst dich wirklich nur wichtigmachen.

    *Prust*, su meinst doch wohl nicht das hier?

    x/(x/4), x/(x/8), x*(x/(x/4), x*(x/(x/8)), x/(x*(x/...
    

    ROFL 😃

    Warts mal ab... irgendwann verstehst du warum ich lache...

    randa schrieb:

    Was du bisher nicht verstanden hast, ist, das es nicht drauf ankommt, ob du 10, 14, 20, oder 30% Performance gewinnst.

    Also wenn ich durch ein paar Änderungen "nur" 10% Performance gewinne dann mache ich sie! Intel ist auch doof, oder? Entwickeln die nen Dothan um ein paar Prozent rauszuholen...



  • MaSTaH schrieb:

    Also wenn ich durch ein paar Änderungen "nur" 10% Performance gewinne dann mache ich sie! Intel ist auch doof, oder? Entwickeln die nen Dothan um ein paar Prozent rauszuholen...

    Die frage ist eigentlich wo ich die 10% schaffe
    wenn ich zum Bsp FLDPI 10%schneller mach bringt das nicht wirklich was.
    bei IMUL doch schon ehr.
    bei der FFT kan man noch so viel schiften wenn man sein Vector nicht in gtössen zur basis 2 hat verliert man alles wieder.
    und was nutzt im Bubblesort nen superschneller Swap algo?
    Optimierung ist immer eine frage der Stelle an der sie geschiet.



  • b7f7 schrieb:

    MStimer mt;// Hier fav timer
        mt.start();
        int i=2;
      //  _asm{int 3}
        for(unsigned int j=0;j<100000000;++j)
          i=(i*i)/i;
        mt.end();
        mt.start();
        for(unsigned int k=0;k<100000000;++k)
          i=(i<<1)/i;
        mt.end();
        cout<<endl<<i<<endl;// gegen optimierung
    

    output
    3.8352
    3.108

    lol der ist echt geil 😃 *weglach*

    jeder weiss schliesslich, dass i<<1 i quadriert 🤡

    oder wolltest du zeigen, dass das quadrieren langsamer ist als das mit 2 multiplizieren. :p



  • japro schrieb:

    oder wolltest du zeigen, dass das quadrieren langsamer ist als das mit 2 multiplizieren. :p

    für 2 machen beide das gleiche oder nicht?
    asso und warum da i*i steht liegt daran damit der Compiler kein shift draus baut



  • ja nur ist i eine variable und der sinn einer variable ist nun mal der variabel zu sein (bei mir jedenfalls).

    ausserdem ist es sinnlos rechungen mit einer variable anzustellen deren wert man sowieso kennt oder sogar voraussetzt. wo soll man sowas brauchen?



  • japro schrieb:

    ja nur ist i eine variable und der sinn einer variable ist nun mal der variabel zu sein (bei mir jedenfalls).

    ausserdem ist es sinnlos rechungen mit einer variable anzustellen deren wert man sowieso kennt oder sogar voraussetzt.

    es geht darum was fixer ist ne multiplication oder nen shift



  • btw wenn man nicht noch cout<<i; macht ersetzt der compiler alles dur ret



  • volatile ist dabei manchmal eine Hilfe. Amsonsten sind solche Progrämmchen meisten von wenig wert. Man müsste sich dann auf jeden Fall mal den Assembler-Code ansehen.



  • b7f7 schrieb:

    es geht darum was fixer ist ne multiplication oder nen shift

    es ist aber ein unterschied, ob du eine variable mit einer anderen variable (z.b. mit sich selbst) multiplizierst, oder mit einer konstante...
    d.h. i<<1 musst du wenn schon mit der operation i*2 vergleichen. dass irgendeine multiplikation schneller oder langsamer als irgendein bitshift ist wird dir jeder auch ohne beweis glauben.

    wenn du beweisen willst, dass äpfel schneller fallen als birnen hast du auch nicht viel davon, wenn du die birne auf dem mond fallen lässt und den apfel auf der venus.



  • japro schrieb:

    b7f7 schrieb:

    es geht darum was fixer ist ne multiplication oder nen shift

    es ist aber ein unterschied, ob du eine variable mit einer anderen variable (z.b. mit sich selbst) multiplizierst, oder mit einer konstante...
    d.h. i<<1 musst du wenn schon mit der operation i*2 vergleichen. dass irgendeine multiplikation schneller oder langsamer als irgendein bitshift ist wird dir jeder auch ohne beweis glauben.

    wenn du beweisen willst, dass äpfel schneller fallen als birnen hast du auch nicht viel davon, wenn du die birne auf dem mond fallen lässt und den apfel auf der venus.

    1. es passt aber zu dem problem das hier besprochen wurde.

    2. das ist eine Frage der Position wenn ich,von aussen auf die Galaxis schauen , den Apfel aus 1mm ÜberVenusOberfläche fallen lasse, ist er immer noch schneller als, wenn ich die birne auf dem mond ausreichend beschleunigt entgegen der Rotationsrichtung der Galaxis fallen lasse.
    Ausserdem ist geschwindigkeit keine frage der wirkenden beschleunigung sondern eine frage der Reibung, Fallhöhe usw. was das Fallen auf der Venus etwas problematisch macht denk ich.



  • b7f7 schrieb:

    Ausserdem ist geschwindigkeit keine frage der wirkenden beschleunigung sondern eine frage der Reibung, Fallhöhe usw. was das Fallen auf der Venus etwas problematisch macht denk ich.

    hmm, also ich habe nächste woche meine physik matur und dachte ich hätte alles im griff. aber nach diesem schocker (geschwindigkeit ist keine frage der beschleunigung, aber der reibung) muss ich wohl alles nochmal repetieren...

    nur so als anmerkung... reibung ist eine kraft welche dividiert durch die masse des objektes die wirkende beschlenigung ergibt. ich schlussfolgere also, dass reibung auch nichts mit der geschwindigkeit zu tun hat.

    ausserdem bin ich mir darüber nicht im klare, warum das fallenlassen auf der venus ein problem sein soll? ok, der apfel würde wohl auf der venus nicht lange durchhalten, aber die asche des apfels würde runterfallen, da bin ich mir sicher. (wobei vielleicht gibts da auch wind.....)



  • ich hab auch mal einen "sinnvollen" test gemacht:

    int function1(int i)
    {
       return i<<1;
    }
    
    int function2(int i)
    {
       return i*2;
    }
    
    int main()
    {
       cout << function1(rand());  
       cout << function2(rand());
    }
    

    wie ich erwartet hatte macht der compiler beide funktionen zum selben code... erstaunlich ist aber, dass weder ein shift noch eine multiplikation vorkommt. er addiert i einfach zu sich selbst:

    .align 2
    .globl __Z9function1i
    	.def	__Z9function1i;	.scl	2;	.type	32;	.endef
    __Z9function1i:
    LFB1:
    	pushl	%ebp
    LCFI0:
    	movl	%esp, %ebp
    LCFI1:
    	movl	8(%ebp), %eax
    	addl	%eax, %eax
    	popl	%ebp
    	ret
    LFE1:
    	.align 2
    .globl __Z9function2i
    	.def	__Z9function2i;	.scl	2;	.type	32;	.endef
    __Z9function2i:
    LFB2:
    	pushl	%ebp
    LCFI2:
    	movl	%esp, %ebp
    LCFI3:
    	movl	8(%ebp), %eax
    	addl	%eax, %eax
    	popl	%ebp
    	ret
    LFE2:
    

    schlussfolgerung: der compiler weiss es eh besser und diese mikrooptimierungen, die schon seit etwa 20 jahren in programmiererkreisen kursieren, sind (man glaubt es kaum) auch schon zu den compilerprogrammierern vorgedrungen und die haben die in ihre compiler eingebaut 😮.
    da sag ich nur: DIESE SCHWEINE wir geben uns hier 8 threadseiten lang mühe und den compiler interessiert das nicht die bohne!

    ändert man den code übrigens zu

    int function1(int i)
    {
       return i<<2;
    }
    
    int function2(int i)
    {
       return i*4;
    }
    

    ab, dann wird die multiplikation durch einen shift ersetzt... daher sollte man hier wohl nicht das nehmen was "optimierter" aussieht, sondern das, was der code darstellen soll. wenn es um arithmetik get multipliziert man und wenn es um bitoperationen geht dann shiftet man.



  • Es geht ja nicht darum, ob man Shifts schreibt oder Multiplikationen. Es geht darum, dass wenn man irgendwas mit 250 hat, dass man vielleicht stattdessen 256 nimmt.

    Mehrdimensionales Array 3x3:

    AAAXBBBXCCCX
    

    Hier hab ich einfach mal frech eine 4x4 Array draus gemacht und Dummys eingesetzt. Jetzt komm ich von auf [x,0] mit x*4 ( == << 2) anstatt *3 zu rechnen.

    Dass der Compiler aus *4 nen << 2 macht, hat ja nie einer (wirklich nicht?!? 🕶 ) bestritten.

    und diese mikrooptimierungen, die schon seit etwa 20 jahren in programmiererkreisen kursieren, sind (man glaubt es kaum) auch schon zu den compilerprogrammierern vorgedrungen und die haben die in ihre compiler eingebaut 😮 .

    Zumindest das hast du schön gesagt. 😃



  • Leute können wir nun zu einem Fazit kommen was nun schneller ist? 😕



  • b7f7 schrieb:

    MaSTaH schrieb:

    Also wenn ich durch ein paar Änderungen "nur" 10% Performance gewinne dann mache ich sie! Intel ist auch doof, oder? Entwickeln die nen Dothan um ein paar Prozent rauszuholen...

    Die frage ist eigentlich wo ich die 10% schaffe

    Ich denke die 80:20-Regel wurde oft genug erwähnt.

    Wobei es doch nicht so ist, dass der Compiler zu dumm ist um ne Multiplikation mit einer konstanten 2er-Potenz zu erkennen. Wichtig ist, dass man bei den wichtigen 20 Prozent nicht so oft in die Verlegenheit kommt eine Multiplikation (oder noch teurer Division) mit nicht-Zweierpotenzen zu verwenden, indem man z.B. bei Texturen oder Auflösungen die Dimensionen in Zweierpotenzen, oder zumindest Kombinationen davon (32+64+128+256=480; 128+512=640; 512+256=768; 1024; 128+1024=1152; 256+1024=1280 ... Zufall?) wählt, damit dann die Divisionen und Multiplikationen möglichst durch Rechts- und Linksshifts ersetzt werden können. Das kann man dann wenn man will selber machen, oder es dem Compiler überlassen (oben hat man ja schön gesehen, dass er z.B. aus i*2 nicht i<<1 sondern i+i macht).



  • japro schrieb:

    hmm, also ich habe nächste woche meine physik matur und dachte ich hätte alles im griff. aber nach diesem schocker (geschwindigkeit ist keine frage der beschleunigung, aber der reibung) muss ich wohl alles nochmal repetieren...

    ist keine Frage der Beschleunigung alein.
    nach deiner aussage würde man auch 2 kugeln fallen lassen können
    beide auf der erde. aber ohne randbedingungen.
    dh. ich lasse eine von 10m höhe fallen und die andere von 1m höhe. und stelle danach fest das die endgeschwindigkeit der ersten höher ist.
    irgendwan kommt man mit denken aber trotzdem dahin das geschwindigkeit von einer kraft und der Zeit der einwirkung abhängt.
    was ich meinte ist das man durch richtige defiition sogar vernünftige werte aus deinem Venus Mond Beispiel ziehn kann.
    man betrachtet halt alles in einem anderen system. aber regal.



  • [quote="MaSTaH"][quote="b7f7"]

    MaSTaH schrieb:

    Wichtig ist, dass man bei den wichtigen 20 Prozent nicht so oft in die Verlegenheit kommt eine Multiplikation (oder noch teurer Division) mit nicht-Zweierpotenzen zu verwenden, indem man z.B. bei Texturen oder Auflösungen die Dimensionen in Zweierpotenzen, oder zumindest Kombinationen davon (32+64+128+256=480; 128+512=640; 512+256=768; 1024; 128+1024=1152; 256+1024=1280 ... Zufall?) wählt, damit dann die Divisionen und Multiplikationen möglichst durch Rechts- und Linksshifts ersetzt werden können. Das kann man dann wenn man will selber machen, oder es dem Compiler überlassen (oben hat man ja schön gesehen, dass er z.B. aus i*2 nicht i<<1 sondern i+i macht).

    Ich denke der Hauptvorteil ist, dass man die natürlichen Busbreiten benutzt und keine memorylücken durch die Datenanordnung hat


Anmelden zum Antworten