www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Which is faster? ulong or double

reply "Janice Caron" <caron800 googlemail.com> writes:
I have this app I've written, and it needs to keep track of an integer
quantity (time in microseconds, as it happens, but that's an
unimportant detail). The point is, there are circumstances where the
numbers involved get bigger than uint.max.

So the question is, given that I'm using a 32-bit platform, should I
switch to ulong, or to double?

ulong sounds the most logical, since the quantity will always be an
integer, but (correct me if I'm wrong) ulongs are emulated in
software, which is fine for add and subtract, but not so fine for
divide; whereas doubles have direct hardware support, and so might
actually end up being faster if there are lots of divides.

Am I talking nonsense? Is there a recommendation?
Sep 27 2007
next sibling parent BCS <ao pathlink.com> writes:
Reply to Janice,

 I have this app I've written, and it needs to keep track of an integer
 quantity (time in microseconds, as it happens, but that's an
 unimportant detail). The point is, there are circumstances where the
 numbers involved get bigger than uint.max.
 
 So the question is, given that I'm using a 32-bit platform, should I
 switch to ulong, or to double?
 
 ulong sounds the most logical, since the quantity will always be an
 integer, but (correct me if I'm wrong) ulongs are emulated in
 software, which is fine for add and subtract, but not so fine for
 divide; whereas doubles have direct hardware support, and so might
 actually end up being faster if there are lots of divides.
 
 Am I talking nonsense? Is there a recommendation?
 
unless you are crunched for space, you might as well use real rather than double. As to real vs ulong, I don't know.
Sep 27 2007
prev sibling next sibling parent Matti Niemenmaa <see_signature for.real.address> writes:
Janice Caron wrote:
 I have this app I've written, and it needs to keep track of an integer
 quantity (time in microseconds, as it happens, but that's an
 unimportant detail). The point is, there are circumstances where the
 numbers involved get bigger than uint.max.
 
 So the question is, given that I'm using a 32-bit platform, should I
 switch to ulong, or to double?
 
 ulong sounds the most logical, since the quantity will always be an
 integer, but (correct me if I'm wrong) ulongs are emulated in
 software, which is fine for add and subtract, but not so fine for
 divide; whereas doubles have direct hardware support, and so might
 actually end up being faster if there are lots of divides.
 
 Am I talking nonsense? Is there a recommendation?
One thing to consider is floating point error, which you won't get with ulongs. You'll have to manually floor the values if you need integer division behaviour. (And even then, things might get odd. I'm not an expert on floating point.) Also, the x86 (I)MUL instructions result in 64-bit values, so at least multiplication is provided by the hardware. And AFAIK GDC can generate 64-bit code, so if you really need speed you can try that. I'd just use ulong and if you find it too slow, benchmark it versus doubles. And reals, too. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Sep 27 2007
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Janice Caron wrote:
 ulong sounds the most logical, since the quantity will always be an
 integer, but (correct me if I'm wrong) ulongs are emulated in
 software, which is fine for add and subtract, but not so fine for
 divide; whereas doubles have direct hardware support, and so might
 actually end up being faster if there are lots of divides.
Ulong divides are emulated in software only if the divisor has any bits set in the high 32 bits. Otherwise, the DIV instruction is used. There are two DIV's if there are high bits set in the dividend. BTW, ulong has more bits of *integral* precision than double or real. As to which is faster, I suggest benchmarking it.
Sep 27 2007
next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/27/07, Walter Bright <newshound1 digitalmars.com> wrote:
 Ulong divides are emulated in software only if the divisor has any bits
 set in the high 32 bits. Otherwise, the DIV instruction is used. There
 are two DIV's if there are high bits set in the dividend.

 BTW, ulong has more bits of *integral* precision than double or real.
Oh excellent! Thank you. :-)
Sep 27 2007
prev sibling parent Don Clugston <dac nospam.com.au> writes:
Walter Bright wrote:
 Janice Caron wrote:
 ulong sounds the most logical, since the quantity will always be an
 integer, but (correct me if I'm wrong) ulongs are emulated in
 software, which is fine for add and subtract, but not so fine for
 divide; whereas doubles have direct hardware support, and so might
 actually end up being faster if there are lots of divides.
Ulong divides are emulated in software only if the divisor has any bits set in the high 32 bits. Otherwise, the DIV instruction is used. There are two DIV's if there are high bits set in the dividend. BTW, ulong has more bits of *integral* precision than double or real.
Specifically: on x86, real has 64 bits of signed precision, but only 63 bits unsigned. On most Pentiums, even 32-bit multiplies and divides are slightly slower than floating point; but converting integers to floats is slow. If there are many multiplies, I'd expect fp to be faster.
Sep 27 2007
prev sibling next sibling parent janderson <askme me.com> writes:
Janice Caron wrote:
 I have this app I've written, and it needs to keep track of an integer
 quantity (time in microseconds, as it happens, but that's an
 unimportant detail). The point is, there are circumstances where the
 numbers involved get bigger than uint.max.
 
 So the question is, given that I'm using a 32-bit platform, should I
 switch to ulong, or to double?
 
 ulong sounds the most logical, since the quantity will always be an
 integer, but (correct me if I'm wrong) ulongs are emulated in
 software, which is fine for add and subtract, but not so fine for
 divide; whereas doubles have direct hardware support, and so might
 actually end up being faster if there are lots of divides.
 
 Am I talking nonsense? Is there a recommendation?
The only way to tell is to benchmark it. Also be aware that different CPUs will perform differently due to many factors like prediction and being able to run certain double and integer operations at the same time. On some processors it may be faster to interleave doubles and uints. Even then some processors can run more floating point operations per cycle then uints (so the intervening may be like 4 doubles and 2 uints per cycle). If you have a fast GPU you can offload this sort of operation to the GPU which if you have enough of these values can be like 300 times faster then the CPU. Then theres SIMD, SIMD2, SIMD3 (specifically SSE2) ect.. which can do a load of operations at once (ie 4 float divides at the same time) and have some 64bit support (doubles, 64 ints) its similar to the GPU but less operations. These I would recommend this over GPU if you want your app to work on more systems. See: http://www.hayestechnologies.com/en/techsimd.htm 64 bit machines + OS of course its pretty fast to do these operations in 64bit. You could try an app optimisation where anything larger then the boundary is stored on a separate list and processed separately (probably easy to do with templates). However the best thing to do is to profile and find out where your bottleneck is and if its even worth the trouble applying these optimizations. Algorithmic operations (in general) are much faster then branching and other operations which cause memory fetching.
Sep 27 2007
prev sibling parent reply "Chris Miller" <chris dprogramming.com> writes:
On Thu, 27 Sep 2007 15:14:04 -0400, Janice Caron <caron800 googlemail.com>  
wrote:

 I have this app I've written, and it needs to keep track of an integer
 quantity (time in microseconds, as it happens, but that's an
 unimportant detail). The point is, there are circumstances where the
 numbers involved get bigger than uint.max.

 So the question is, given that I'm using a 32-bit platform, should I
 switch to ulong, or to double?

 ulong sounds the most logical, since the quantity will always be an
 integer, but (correct me if I'm wrong) ulongs are emulated in
 software, which is fine for add and subtract, but not so fine for
 divide; whereas doubles have direct hardware support, and so might
 actually end up being faster if there are lots of divides.

 Am I talking nonsense? Is there a recommendation?
I just came across this: http://lua-users.org/wiki/FloatingPoint
Oct 03 2007
parent Robert Fraser <fraserofthenight gmail.com> writes:
Chris Miller Wrote:

 On Thu, 27 Sep 2007 15:14:04 -0400, Janice Caron <caron800 googlemail.com>  
 wrote:
 
 I have this app I've written, and it needs to keep track of an integer
 quantity (time in microseconds, as it happens, but that's an
 unimportant detail). The point is, there are circumstances where the
 numbers involved get bigger than uint.max.

 So the question is, given that I'm using a 32-bit platform, should I
 switch to ulong, or to double?

 ulong sounds the most logical, since the quantity will always be an
 integer, but (correct me if I'm wrong) ulongs are emulated in
 software, which is fine for add and subtract, but not so fine for
 divide; whereas doubles have direct hardware support, and so might
 actually end up being faster if there are lots of divides.

 Am I talking nonsense? Is there a recommendation?
I just came across this: http://lua-users.org/wiki/FloatingPoint
I would *hope* that the compiler would be able to optimize this if it could prove that a double-precision floating point would have the same semantics as a long integer... but I guess with stuff like inline ASM plus the fact that doubles don't have the same width as ulong, this is a pipe dream.
Oct 03 2007