Very slow operator float ???



  • Hello.

    I created the color class as follows:

    struct Component
    { //One component of color
    	float value; //The value of component
    
    	inline operator float(void) const {return value;} //In order to operate with components as with float numbers
    
    	... //Some other methods and useful conversion operators.
    };
    
    struct Color
    { //Color
    	Component r,g,b;
    
    	... //Some other methods and useful conversion operators.
    };
    

    Now I doing (for example) the following:

    Color c,c1,c2;
    ...
    c.r.value = c1.r + c2.r*2.0; //In fact I overloaded operator= also, but I omit it here for simplicity
    c.g.value = c1.g + c2.g*2.0;
    c.b.value = c1.b + c2.b*2.0;
    

    In fact my formulas much more complex, but idea the same. The program running time was 40 seconds. I accidentally changed one formula in the program to something like c.r.value = c1.r.value + c2.r.value*2.0; and noticed small speed-up. Then I commented out the Component::operator float and fixed all errors by adding .value everywhere:

    Color c,c1,c2;
    ...
    c.r.value = c1.r.value + c2.r.value*2.0; //Notice .value here
    c.g.value = c1.g.value + c2.g.value*2.0;
    c.b.value = c1.b.value + c2.b.value*2.0;
    

    The program running time reduced to 26 seconds!!!

    How could this happen? I sought that inline operator float will work just as if I write .value . All optmizations was turned on! Visual Studio 2008.



  • You might have disabled inlining (Debug-Build?!).

    /edit: Aye, obviously not. Still, that's the only thing I can imagine that could have gone wrong here.



  • You are right!

    The project was imported from WS2005 to WS2008, and projects settings were messed up!

    I checked settings in VS2005 and forgot to recheck them in VS2008 😞



  • I still have the following problem:

    float a;
    double b;
    
    a += b; //Fast, but warning here about "possible loss of data"
    a += static_cast<float>( b ); //No warning, but VERY SLOW
    


  • ich bezweifle, dass es da einen laufzeitunterschied gobt, da static_casts dem compiler eigendlich nur mitteilt, dass die konvertierung gewollt ist.
    Es sollte eigendlich identischer code generiert werden.



  • Well, I get following assembler-output (Visual C++ 2008, full optimizations).

    ; 6    : 	a += b;
    
    fld	DWORD PTR ?a@@3MA			; a
    fadd	QWORD PTR ?b@@3NA			; b
    fstp	DWORD PTR ?a@@3MA			; a
    
    ; 11   : 	a += static_cast <float> (b);
    
    fld	QWORD PTR ?b@@3NA			; b
    fstp	DWORD PTR tv133[esp+4]
    fld	DWORD PTR tv133[esp+4]
    fadd	DWORD PTR ?a@@3MA			; a
    fstp	DWORD PTR ?a@@3MA			; a
    

    Somehow it seems to be correct, what SAn described. You can get the same assembler-output for both operations, if you enable "Floating-Point-Model: Fast" in section "Code Generation". Precise and Strict will not work either.

    Gruß (Sorry for my English, but I think/hope you understood it)
    Don06



  • Don06 schrieb:

    You can get the same assembler-output for both operations, if you enable "Floating-Point-Model: Fast" in section "Code Generation".

    Thank you! This really helps me.

    By the way, how do you managed to produce assembler output in Visual Studio?



  • C/C++ -> Output Files -> Assembler Output
    You should have diffrent options, I prefer "Assembly With Source Code".


Anmelden zum Antworten