x*1/y vs. x/y
Why is x*1.0/y supposedly faster than x/y?
There''s a division in both, and in the first there is a division + multiplication. It seems that the first example should be slower than the second.
--------------------------I guess this is where most people put a famous quote..."Everything is funnier with monkey''s" - Unknown
March 01, 2001 10:36 AM
if you were to add two constants, like this:
x = 4 + 4;
your compiler knows how to add two constants, and just resolves it to a single assignment:
x = 8;
i think it would be the same with multiplication:
x = 1 * y
would give you:
x = y;
of course, in your problem, you are using 1.0, which would CAST the type of variables involved to floats. so:
x = 1.0 * y;
would give you:
x = (float) y;
i think that is what is happening. (someone correct me if i''m wrong.) BUT, i doubt if floats being divided and multed are speedier than ints.
farmersckn
x = 4 + 4;
your compiler knows how to add two constants, and just resolves it to a single assignment:
x = 8;
i think it would be the same with multiplication:
x = 1 * y
would give you:
x = y;
of course, in your problem, you are using 1.0, which would CAST the type of variables involved to floats. so:
x = 1.0 * y;
would give you:
x = (float) y;
i think that is what is happening. (someone correct me if i''m wrong.) BUT, i doubt if floats being divided and multed are speedier than ints.
farmersckn
Some graphics cards and possibly CPUs are optimized to process floats. Sometimes that leads to ints being a bit slower. I have a Diamond Viper II card which runs 3d on my 700Duron no problem. But for 2d it goes slower than a PC with a 466Celeron and onboard video. That same PC can''t come close to the 3d ability my computer has.
Ben
http://therabbithole.redback.inficad.com
Ben
http://therabbithole.redback.inficad.com
Multiplying by reciprocals is faster if you want to divide by a number more than once. So this:
x = x/z;
y = y/z;
is much slower than this:
r = 1/z;
x = x*r;
y = y*r;
~CGameProgrammer( );
x = x/z;
y = y/z;
is much slower than this:
r = 1/z;
x = x*r;
y = y*r;
~CGameProgrammer( );
~CGameProgrammer( );
Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Yup. I didn't believe it so I had to try it myself. Here's my test program:
(BTW, I completely cheezed this the first time, I've re-editted it)
Here's the assembly listings for f1 and f2:
9 instructions for f1, 10 for f2. How's the time now?
Only a slight gain, but still a gain.
If I comment-out one of the lines, so that only one computation is made, f2 is actually slightly (very slightly) slower.
So it looks like this is something to do only with 2+ divisions by the same value.
edit--to fix the stupid code mistake.
Edited by - Stoffel on March 1, 2001 10:33:59 PM
(BTW, I completely cheezed this the first time, I've re-editted it)
|
Here's the assembly listings for f1 and f2:
PUBLIC ?f1@@YAXAAN0N@Z ; f1EXTRN __fltused:NEAR; COMDAT ?f1@@YAXAAN0N@Z_TEXT SEGMENT_x$ = 8_y$ = 12_d$ = 16?f1@@YAXAAN0N@Z PROC NEAR ; f1, COMDAT; 8 : x = x / d; mov eax, DWORD PTR _x$[esp-4] fld QWORD PTR [eax] fdiv QWORD PTR _d$[esp-4] fstp QWORD PTR [eax]; 9 : y = y / d; mov eax, DWORD PTR _y$[esp-4] fld QWORD PTR [eax] fdiv QWORD PTR _d$[esp-4] fstp QWORD PTR [eax]; 10 : } ret 0?f1@@YAXAAN0N@Z ENDP ; f1_TEXT ENDSPUBLIC __real@8@3fff8000000000000000PUBLIC ?f2@@YAXAAN0N@Z ; f2; COMDAT __real@8@3fff8000000000000000; File C:\Projects\test\test.cppCONST SEGMENT__real@8@3fff8000000000000000 DQ 03ff0000000000000r ; 1CONST ENDS; COMDAT ?f2@@YAXAAN0N@Z_TEXT SEGMENT_x$ = 8_y$ = 12_d$ = 16?f2@@YAXAAN0N@Z PROC NEAR ; f2, COMDAT; 13 : double r = 1.0/d; fld QWORD PTR __real@8@3fff8000000000000000 fdiv QWORD PTR _d$[esp-4]; 14 : x = x * r; mov eax, DWORD PTR _x$[esp-4] fld ST(0) fmul QWORD PTR [eax] fstp QWORD PTR [eax]; 15 : y = y * r; mov eax, DWORD PTR _y$[esp-4] fmul QWORD PTR [eax] fstp QWORD PTR [eax]; 16 : } ret 0?f2@@YAXAAN0N@Z ENDP ; f2_TEXT ENDS
9 instructions for f1, 10 for f2. How's the time now?
Time for f1: 12470Time for f2: 11200
Only a slight gain, but still a gain.
If I comment-out one of the lines, so that only one computation is made, f2 is actually slightly (very slightly) slower.
So it looks like this is something to do only with 2+ divisions by the same value.
edit--to fix the stupid code mistake.
Edited by - Stoffel on March 1, 2001 10:33:59 PM
Just a small detail, but you might want to multiple by r instead of d in f2. It is generally better to compare two routines that do the same thing rather than two that do two entirely differant things.
Keys to success: Ability, ambition and opportunity.
If you look at the disassembly, the double r = 1.0/d; was removed completely because it wasn''t being used for anything. That could make up the difference in speed...
hey man, you forget something
probably blind...
look at your assembly, the divide in f2 is not there, why? because you dont use the variable r.
then the compiler removed that line, its why the function is much faster...
cheater!!!
probably blind...
look at your assembly, the divide in f2 is not there, why? because you dont use the variable r.
then the compiler removed that line, its why the function is much faster...
cheater!!!
cyberg- cyberg_coder@hotmail.com- http://members.xoom.com/cybergsoft
Doy. OK, I fixed it & re-editted my post. Nice catch. Guess I shouldn''t try to put out fires at work AND post here at the same time.
Make sure to test them with seperately, or the CPU can predict what the answer will be for the second calculation, and make it faster.
"Finger to spiritual emptiness underlying everything." -- How a C manual referred to a "pointer to void." --Things People Said
http://www.gdarchive.net/druidgames/
"Finger to spiritual emptiness underlying everything." -- How a C manual referred to a "pointer to void." --Things People Said
http://www.gdarchive.net/druidgames/
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement