Re: using MFC VC++ - which is more efficient - float or double?



Joseph M. Newcomer wrote:
See below:
See below...
On Wed, 22 Jul 2009 09:46:02 -0700, JRGlide <JRGlide@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:

First, I have to admit that I'm not up on the latest hardware. So everthing I'm about to say may be null and void.

I don't think its true that the hardware does everything as doubles. As far as I know everything is floating point and doubles takes extra processing to emulate. I've measure it in the past and doubles were about five times slower than floats. Again, maybe this has now changed.
****
Strike one. Not true. The hardware works with 80-bit floating point representation. So
there's nothing that is 'saved' by using float. Since you have not said under what
context you made the measurements, they have no relevance to the discussion.
****
I can think of three reasons to use floats instead of doubles if you don't need the precision:

1. In case I'm right and doubles are slower. It would be easy enough to do a timing study and find out. Just do two loops 100 million times - multiply two floats in one and two doubles in the other and time them. Even better, do a divide.
****
Floats are slower. See data and sample program below.
****
2. If you are working with large sets of data, then memory. We use MATLAB a lot where I work and MATLAB does everything as doubles. This gets to be a problem sometimes even with a Gig or several Gigs of memory. And if you happen to be storing the data, the files are twice as large. Why waste memory/storage for nothing?
****
Probably because memory is largely irrelevant on nearly every kind of app. Unless you
really need massive arrays, the discussion of size is irrelevant. For large data
structures, it matters a lot. I know of one machine that ran with 8-bit floating point (3
bits exponent, 5 bits mantissa) and all functions were done with table lookup. But it is
a red herring if the discussion is about performance.
3. So that the next person looking at your code doesn't scratch their heads wondering why you did everything in double precision.
****
More seriously, I tend to scratch my head and wonder why anyone bothers to do anything in
float!
joe
****

"Mechi" wrote:

Hi!
I've been told that even if I only need small numbers 9up to 100) I should still use int - since it is more efficient in VC++.
What about float and double? precision isn't important - which type is "built-in" and will work faster/more efficiently?
Thanks,
Mechi
*****
Tests are run on a 1.81GHz AMD64 dual CPU dual-core system running 32-bit Vista-32
Ultimate SP2.

VS2008, debug mode
TOTAL TOTAL-NULL
No computation: 0.003317740
Float computation: 0.004153321 0.000835581
Double computation: 0.004058616 0.000740876

No computation: 0.003304051
Float computation: 0.004180699 0.000876648
Double computation: 0.004056940 0.000752889

No computation: 0.003267175
Float computation: 0.004173994 0.000906819
Double computation: 0.004041854 0.000774679

VS2008, release mode
/O2 /Oi /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FD /EHsc /MD
/Gy /c /Zi /TP .\fdub.cpp
]

No computation: 0.000001676
Float computation: 0.001328381 0.001326705
Double computation: 0.000838375 0.000836699

No computation: 0.000002794
Float computation: 0.001325587 0.001322794
Double computation: 0.000836699 0.000833905

No computation: 0.000002794
Float computation: 0.001326146 0.001323353
Double computation: 0.000835022 0.000832229

// fdub.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

double d = 1.0;
double d2 = 5.0;

float f = 1.0;
float f2 = 5.0;

void NoComputation()
{
return;
}

void DoubleComputation()
{
d = d * 2.141632 / (d2 * 3.141592);
d2 *= 1.1416;
}

void FloatComputation()
{
f = f * 2.141632f / (f2 * 3.141592f);
f2 *= 1.1416f;
}

const int MAX_TESTS = 100000;

int _tmain(int argc, _TCHAR* argv[])
{
LARGE_INTEGER start;
LARGE_INTEGER end;
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);

QueryPerformanceCounter(&start);
for(int i = 0; i < MAX_TESTS; i++)
NoComputation();
QueryPerformanceCounter(&end);
double tn = (double)(end.QuadPart - start.QuadPart)/ (double)freq.QuadPart;
_tprintf(_T("No computation: %1.9f\n"), tn);

QueryPerformanceCounter(&start);
for(int i = 0; i < MAX_TESTS; i++)
FloatComputation();
QueryPerformanceCounter(&end);

double tf = (double)(end.QuadPart - start.QuadPart)/ (double)freq.QuadPart;
_tprintf(_T("Float computation: %1.9f %1.9f\n"),tf , tf - tn);

QueryPerformanceCounter(&start);
for(int i = 0; i < MAX_TESTS; i++)
DoubleComputation();
QueryPerformanceCounter(&end);

double td = (double)(end.QuadPart - start.QuadPart)/ (double)freq.QuadPart;
_tprintf(_T("Double computation: %1.9f %1.9f\n"), td, td - tn);

return 0;
}
============================================
Now look at the code. The code is IDENTICAL except for the operand sizes! But the float
code is consistently slower!

?FloatComputation@@YAXXZ PROC ; FloatComputation, COMDAT

; 25 : f = f * 2.141632f / (f2 * 3.141592f);

00000 d9 05 00 00 00
00 fld DWORD PTR ?f@@3MA ; f
00006 dc 0d 00 00 00
00 fmul QWORD PTR __real@4001221000000000
0000c d9 05 00 00 00
00 fld DWORD PTR ?f2@@3MA ; f2
00012 dd 05 00 00 00
00 fld QWORD PTR __real@400921fb00000000
00018 d8 c9 fmul ST(0), ST(1)
0001a de fa fdivp ST(2), ST(0)
0001c d9 c9 fxch ST(1)
0001e d9 1d 00 00 00
00 fstp DWORD PTR ?f@@3MA ; f

; 26 : f2 *= 1.1416f;

00024 dc 0d 00 00 00
00 fmul QWORD PTR __real@3ff243fe60000000
0002a d9 1d 00 00 00
00 fstp DWORD PTR ?f2@@3MA ; f2

; 27 : }

00030 c3 ret 0
?FloatComputation@@YAXXZ ENDP ; FloatComputation

?DoubleComputation@@YAXXZ PROC ; DoubleComputation, COMDAT

; 19 : d = d * 2.141632 / (d2 * 3.141592);

00000 dd 05 00 00 00
00 fld QWORD PTR ?d@@3NA ; d
00006 dc 0d 00 00 00
00 fmul QWORD PTR __real@4001220ff540895d
0000c dd 05 00 00 00
00 fld QWORD PTR ?d2@@3NA ; d2
00012 dd 05 00 00 00
00 fld QWORD PTR __real@400921fafc8b007a
00018 d8 c9 fmul ST(0), ST(1)
0001a de fa fdivp ST(2), ST(0)
0001c d9 c9 fxch ST(1)
0001e dd 1d 00 00 00
00 fstp QWORD PTR ?d@@3NA ; d

; 20 : d2 *= 1.1416;

00024 dc 0d 00 00 00
00 fmul QWORD PTR __real@3ff243fe5c91d14e
0002a dd 1d 00 00 00
00 fstp QWORD PTR ?d2@@3NA ; d2

; 21 : }

00030 c3 ret 0
?DoubleComputation@@YAXXZ ENDP ; DoubleComputation

Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joe,

I found your results interesting. I suffer from having worked in an environment where storage (both memory and secondary) was at a premium. So float was the primary choice. Breaking that habit has been painful.

I disagree with the an earlier statement about integer math not being significantly faster.

I added an IntComputation() function and got much faster results. I know I'm not really comparing apples to apples in that I can't make identical computations using fixed point. I also suspect that the compiler will be better at optimization with integers.


I added:

long x=1;
long x2 = 5;

void IntComputation()
{
x2 *= 17;
x = x * 2 / (x2 * 3);
x2 /= 17;
}

As well as the appropriate _tprintf.

The results I got with VS2008 in debug w/ Intel Core 2 Duo @ 3GHz on WinXP SP2:

No computation: 0.024682403
Float computation: 0.279541978 0.254859575
Double computation: 0.278127513 0.253445109
Int computation: 0.033386237 0.008703834

Steve
.



Relevant Pages

  • Re: using MFC VC++ - which is more efficient - float or double?
    ... I'm about to say may be null and void. ... I don't think its true that the hardware does everything as doubles. ... there's nothing that is 'saved' by using float. ... If you are working with large sets of data, then memory. ...
    (microsoft.public.vc.mfc)
  • Re: using MFC VC++ - which is more efficient - float or double?
    ... Measurements made in debug mode are usually useless. ... float f2 = 5.0; ... __declspecvoid DoubleComputation() ... I don't think its true that the hardware does everything as doubles. ...
    (microsoft.public.vc.mfc)
  • Re: using MFC VC++ - which is more efficient - float or double?
    ... float f2 = 5.0; ... int I = 5000000; ... __declspecvoid DoubleComputation() ... As far as I know everything is floating point and doubles takes extra processing to emulate. ...
    (microsoft.public.vc.mfc)
  • Re: why float
    ... A double *is* a float with more precision. ... It is possibly to do with spurious precision in the doubles - in numerical ... I think it depends on teh algorithm as well. ... single-precision in order to stop rounding errors from amplifying ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: using MFC VC++ - which is more efficient - float or double?
    ... and now double is 1.03x float. ... I don't think its true that the hardware does everything as doubles. ... If you are working with large sets of data, then memory. ... still use int - since it is more efficient in VC++. ...
    (microsoft.public.vc.mfc)

Loading