www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.math performance (SSE vs. real)

reply "David Nadlinger" <code klickverbot.at> writes:
Hi all,

right now, the use of std.math over core.stdc.math can cause a 
huge performance problem in typical floating point graphics code. 
An instance of this has recently been discussed here in the 
"Perlin noise benchmark speed" thread [1], where even LDC, which 
already beat DMD by a factor of two, generated code more than 
twice as slow as that by Clang and GCC. Here, the use of floor() 
causes trouble. [2]

Besides the somewhat slow pure D implementations in std.math, the 
biggest problem is the fact that std.math almost exclusively uses 
reals in its API. When working with single- or double-precision 
floating point numbers, this is not only more data to shuffle 
around than necessary, but on x86_64 requires the caller to 
transfer the arguments from the SSE registers onto the x87 stack 
and then convert the result back again. Needless to say, this is 
a serious performance hazard. In fact, this accounts for an 1.9x 
slowdown in the above benchmark with LDC.

Because of this, I propose to add float and double overloads (at 
the very least the double ones) for all of the commonly used 
functions in std.math. This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls effectively 
widen the calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without 
context, of course.

What do you think?

Cheers,
David


[1] http://forum.dlang.org/thread/lo19l7$n2a$1 digitalmars.com
[2] Fun fact: As the program happens only deal with positive 
numbers, the author could have just inserted an int-to-float 
cast, sidestepping the issue altogether. All the other language 
implementations have the floor() call too, though, so it doesn't 
matter for this discussion.
Jun 26 2014
next sibling parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Friday, 27 June 2014 at 01:31:17 UTC, David Nadlinger wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause a 
 huge performance problem in typical floating point graphics 
 code. An instance of this has recently been discussed here in 
 the "Perlin noise benchmark speed" thread [1], where even LDC, 
 which already beat DMD by a factor of two, generated code more 
 than twice as slow as that by Clang and GCC. Here, the use of 
 floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, 
 the biggest problem is the fact that std.math almost 
 exclusively uses reals in its API. When working with single- or 
 double-precision floating point numbers, this is not only more 
 data to shuffle around than necessary, but on x86_64 requires 
 the caller to transfer the arguments from the SSE registers 
 onto the x87 stack and then convert the result back again. 
 Needless to say, this is a serious performance hazard. In fact, 
 this accounts for an 1.9x slowdown in the above benchmark with 
 LDC.

 Because of this, I propose to add float and double overloads 
 (at the very least the double ones) for all of the commonly 
 used functions in std.math. This is unlikely to break much 
 code, but:
  a) Somebody could rely on the fact that the calls effectively 
 widen the calculation to 80 bits on x86 when using type 
 deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without 
 context, of course.

 What do you think?

 Cheers,
 David


 [1] http://forum.dlang.org/thread/lo19l7$n2a$1 digitalmars.com
 [2] Fun fact: As the program happens only deal with positive 
 numbers, the author could have just inserted an int-to-float 
 cast, sidestepping the issue altogether. All the other language 
 implementations have the floor() call too, though, so it 
 doesn't matter for this discussion.
I honestly alway thought that it was a little odd that it forced conversion to real. Personally I support this. It would also make generic code that calls math functions more simple as it wouldn't require casts back.
Jun 26 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Jun 27, 2014 at 02:09:59AM +0000, Tofu Ninja via Digitalmars-d wrote:
 On Friday, 27 June 2014 at 01:31:17 UTC, David Nadlinger wrote:
[...]
Because of this, I propose to add float and double overloads (at the
very least the double ones) for all of the commonly used functions in
std.math.  This is unlikely to break much code, but:
 a) Somebody could rely on the fact that the calls effectively widen
 the calculation to 80 bits on x86 when using type deduction.
 b) Additional overloads make e.g. "&floor" ambiguous without
 context, of course.

What do you think?
[...]
 I honestly alway thought that it was a little odd that it forced
 conversion to real. Personally I support this. It would also make
 generic code that calls math functions more simple as it wouldn't
 require casts back.
I support this too. T -- It is impossible to make anything foolproof because fools are so ingenious. -- Sammy
Jun 26 2014
parent reply Jerry <jlquinn optonline.net> writes:
"H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:

 On Fri, Jun 27, 2014 at 02:09:59AM +0000, Tofu Ninja via Digitalmars-d wrote:
 On Friday, 27 June 2014 at 01:31:17 UTC, David Nadlinger wrote:
[...]
Because of this, I propose to add float and double overloads (at the
very least the double ones) for all of the commonly used functions in
std.math.  This is unlikely to break much code, but:
 a) Somebody could rely on the fact that the calls effectively widen
 the calculation to 80 bits on x86 when using type deduction.
 b) Additional overloads make e.g. "&floor" ambiguous without
 context, of course.

What do you think?
[...]
 I honestly alway thought that it was a little odd that it forced
 conversion to real. Personally I support this. It would also make
 generic code that calls math functions more simple as it wouldn't
 require casts back.
I support this too.
Me three. This seems like an unnecessary pessimisation and it would be irritating for D to become associated with slow fp math.
Jun 26 2014
parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Thu, 2014-06-26 at 23:28 -0400, Jerry via Digitalmars-d wrote:
 "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
=20
 On Fri, Jun 27, 2014 at 02:09:59AM +0000, Tofu Ninja via Digitalmars-d =
wrote:
 On Friday, 27 June 2014 at 01:31:17 UTC, David Nadlinger wrote:
[...]
Because of this, I propose to add float and double overloads (at the
very least the double ones) for all of the commonly used functions in
std.math.  This is unlikely to break much code, but:
 a) Somebody could rely on the fact that the calls effectively widen
 the calculation to 80 bits on x86 when using type deduction.
 b) Additional overloads make e.g. "&floor" ambiguous without
 context, of course.

What do you think?
[...]
 I honestly alway thought that it was a little odd that it forced
 conversion to real. Personally I support this. It would also make
 generic code that calls math functions more simple as it wouldn't
 require casts back.
I support this too.
=20 Me three. This seems like an unnecessary pessimisation and it would be irritating for D to become associated with slow fp math.
So has anyone got a pull request ready? --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 26 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 27 June 2014 02:31, David Nadlinger via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause a huge
 performance problem in typical floating point graphics code. An instance of
 this has recently been discussed here in the "Perlin noise benchmark speed"
 thread [1], where even LDC, which already beat DMD by a factor of two,
 generated code more than twice as slow as that by Clang and GCC. Here, the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, the biggest
 problem is the fact that std.math almost exclusively uses reals in its API.
 When working with single- or double-precision floating point numbers, this
 is not only more data to shuffle around than necessary, but on x86_64
 requires the caller to transfer the arguments from the SSE registers onto
 the x87 stack and then convert the result back again. Needless to say, this
 is a serious performance hazard. In fact, this accounts for an 1.9x slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads (at the very
 least the double ones) for all of the commonly used functions in std.math.
 This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls effectively widen the
 calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without context, of
 course.

 What do you think?

 Cheers,
 David
This is the reason why floor is slow, it has an array copy operation. --- auto vu = *cast(ushort[real.sizeof/2]*)(&x); --- I didn't like it at the time I wrote, but at least it prevented the compiler (gdc) from removing all bit operations that followed. If there is an alternative to the above, then I'd imagine that would speed up floor by tenfold. Regards Iain
Jun 26 2014
prev sibling next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 27 June 2014 07:14, Iain Buclaw <ibuclaw gdcproject.org> wrote:
 On 27 June 2014 02:31, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause a huge
 performance problem in typical floating point graphics code. An instance of
 this has recently been discussed here in the "Perlin noise benchmark speed"
 thread [1], where even LDC, which already beat DMD by a factor of two,
 generated code more than twice as slow as that by Clang and GCC. Here, the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, the biggest
 problem is the fact that std.math almost exclusively uses reals in its API.
 When working with single- or double-precision floating point numbers, this
 is not only more data to shuffle around than necessary, but on x86_64
 requires the caller to transfer the arguments from the SSE registers onto
 the x87 stack and then convert the result back again. Needless to say, this
 is a serious performance hazard. In fact, this accounts for an 1.9x slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads (at the very
 least the double ones) for all of the commonly used functions in std.math.
 This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls effectively widen the
 calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without context, of
 course.

 What do you think?

 Cheers,
 David
This is the reason why floor is slow, it has an array copy operation. --- auto vu = *cast(ushort[real.sizeof/2]*)(&x); --- I didn't like it at the time I wrote, but at least it prevented the compiler (gdc) from removing all bit operations that followed. If there is an alternative to the above, then I'd imagine that would speed up floor by tenfold.
Can you test with this? https://github.com/D-Programming-Language/phobos/pull/2274 Float and Double implementations of floor/ceil are trivial and I can add later.
Jun 26 2014
parent reply "hane" <han.ehit.suzi.0 gmail.com> writes:
On Friday, 27 June 2014 at 06:48:44 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 On 27 June 2014 07:14, Iain Buclaw <ibuclaw gdcproject.org> 
 wrote:
 On 27 June 2014 02:31, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause 
 a huge
 performance problem in typical floating point graphics code. 
 An instance of
 this has recently been discussed here in the "Perlin noise 
 benchmark speed"
 thread [1], where even LDC, which already beat DMD by a 
 factor of two,
 generated code more than twice as slow as that by Clang and 
 GCC. Here, the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, 
 the biggest
 problem is the fact that std.math almost exclusively uses 
 reals in its API.
 When working with single- or double-precision floating point 
 numbers, this
 is not only more data to shuffle around than necessary, but 
 on x86_64
 requires the caller to transfer the arguments from the SSE 
 registers onto
 the x87 stack and then convert the result back again. 
 Needless to say, this
 is a serious performance hazard. In fact, this accounts for 
 an 1.9x slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads 
 (at the very
 least the double ones) for all of the commonly used functions 
 in std.math.
 This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls 
 effectively widen the
 calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without 
 context, of
 course.

 What do you think?

 Cheers,
 David
This is the reason why floor is slow, it has an array copy operation. --- auto vu = *cast(ushort[real.sizeof/2]*)(&x); --- I didn't like it at the time I wrote, but at least it prevented the compiler (gdc) from removing all bit operations that followed. If there is an alternative to the above, then I'd imagine that would speed up floor by tenfold.
Can you test with this? https://github.com/D-Programming-Language/phobos/pull/2274 Float and Double implementations of floor/ceil are trivial and I can add later.
Nice! I tested with the Perlin noise benchmark, and it got faster(in my environment, 1.030s -> 0.848s). But floor still consumes almost half of the execution time.
Jun 27 2014
next sibling parent reply "David Nadlinger" <code klickverbot.at> writes:
On Friday, 27 June 2014 at 09:37:54 UTC, hane wrote:
 On Friday, 27 June 2014 at 06:48:44 UTC, Iain Buclaw via 
 Digitalmars-d wrote:
 Can you test with this?

 https://github.com/D-Programming-Language/phobos/pull/2274

 Float and Double implementations of floor/ceil are trivial and 
 I can add later.
Nice! I tested with the Perlin noise benchmark, and it got faster(in my environment, 1.030s -> 0.848s). But floor still consumes almost half of the execution time.
Wait, so DMD and GDC did actually emit a memcpy/… here? LDC doesn't, and the change didn't have much of an impact on performance. What _does_ have a significant impact, however, is that the whole of floor() for doubles can be optimized down to roundsd <…>,<…>,0x1 when targeting SSE 4.1, or vroundsd <…>,<…>,<…>,0x1 when targeting AVX. This is why std.math will need to build on top of compiler-recognizable primitives. Iain, Don, how do you think we should handle this? One option would be to build std.math based on an extended core.math with functions that are recognized as intrinsics or suitably implemented in the compiler-specific runtimes. The other option would be for me to submit LDC-specific implementations to Phobos. Cheers, David
Jun 27 2014
parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 27 June 2014 11:47, David Nadlinger via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Friday, 27 June 2014 at 09:37:54 UTC, hane wrote:
 On Friday, 27 June 2014 at 06:48:44 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 Can you test with this?

 https://github.com/D-Programming-Language/phobos/pull/2274

 Float and Double implementations of floor/ceil are trivial and I can add
 later.
Nice! I tested with the Perlin noise benchmark, and it got faster(in my environment, 1.030s -> 0.848s). But floor still consumes almost half of the execution time.
Wait, so DMD and GDC did actually emit a memcpy/… here? LDC doesn't, and the change didn't have much of an impact on performance.
Yes, IIRC _d_arraycopy to be exact (so we loose doubly so!)
 What _does_ have a significant impact, however, is that the whole of floor()
 for doubles can be optimized down to
     roundsd <…>,<…>,0x1
 when targeting SSE 4.1, or
     vroundsd <…>,<…>,<…>,0x1
 when targeting AVX.

 This is why std.math will need to build on top of compiler-recognizable
 primitives. Iain, Don, how do you think we should handle this?
My opinion is that we should have never have pushed a variable sized as the baseline for all floating point computations in the first place. But as we can't backtrace now, overloads will just have to do. I would welcome a DIP to add new core.math intrinsics that could be proven to be useful for the sake of maintainability (and portability). Regards Iain
Jun 27 2014
prev sibling next sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Friday, 27 June 2014 at 09:37:54 UTC, hane wrote:
 Nice! I tested with the Perlin noise benchmark, and it got 
 faster(in my environment, 1.030s -> 0.848s).
 But floor still consumes almost half of the execution time.
Oh, and by the way, my optimized version (simply replace floor() in perlin_noise.d with a call to llvm_floor() from ldc.intrinsics) is 2.8x faster than the original one on my machine (both with -mcpu=native). David
Jun 27 2014
prev sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 27 June 2014 10:37, hane via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Friday, 27 June 2014 at 06:48:44 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 On 27 June 2014 07:14, Iain Buclaw <ibuclaw gdcproject.org> wrote:
 On 27 June 2014 02:31, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause a huge
 performance problem in typical floating point graphics code. An instance
 of
 this has recently been discussed here in the "Perlin noise benchmark
 speed"
 thread [1], where even LDC, which already beat DMD by a factor of two,
 generated code more than twice as slow as that by Clang and GCC. Here,
 the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, the
 biggest
 problem is the fact that std.math almost exclusively uses reals in its
 API.
 When working with single- or double-precision floating point numbers,
 this
 is not only more data to shuffle around than necessary, but on x86_64
 requires the caller to transfer the arguments from the SSE registers
 onto
 the x87 stack and then convert the result back again. Needless to say,
 this
 is a serious performance hazard. In fact, this accounts for an 1.9x
 slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads (at the
 very
 least the double ones) for all of the commonly used functions in
 std.math.
 This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls effectively widen the
 calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without context,
 of
 course.

 What do you think?

 Cheers,
 David
This is the reason why floor is slow, it has an array copy operation. --- auto vu = *cast(ushort[real.sizeof/2]*)(&x); --- I didn't like it at the time I wrote, but at least it prevented the compiler (gdc) from removing all bit operations that followed. If there is an alternative to the above, then I'd imagine that would speed up floor by tenfold.
Can you test with this? https://github.com/D-Programming-Language/phobos/pull/2274 Float and Double implementations of floor/ceil are trivial and I can add later.
Nice! I tested with the Perlin noise benchmark, and it got faster(in my environment, 1.030s -> 0.848s). But floor still consumes almost half of the execution time.
I've done some further improvements in that PR. I'd imagine you'd see a little more juice squeezed out.
Jun 28 2014
prev sibling next sibling parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 27 June 2014 11:31, David Nadlinger via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause a huge
 performance problem in typical floating point graphics code. An instance of
 this has recently been discussed here in the "Perlin noise benchmark speed"
 thread [1], where even LDC, which already beat DMD by a factor of two,
 generated code more than twice as slow as that by Clang and GCC. Here, the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, the biggest
 problem is the fact that std.math almost exclusively uses reals in its API.
 When working with single- or double-precision floating point numbers, this
 is not only more data to shuffle around than necessary, but on x86_64
 requires the caller to transfer the arguments from the SSE registers onto
 the x87 stack and then convert the result back again. Needless to say, this
 is a serious performance hazard. In fact, this accounts for an 1.9x slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads (at the very
 least the double ones) for all of the commonly used functions in std.math.
 This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls effectively widen the
 calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without context, of
 course.

 What do you think?

 Cheers,
 David


 [1] http://forum.dlang.org/thread/lo19l7$n2a$1 digitalmars.com
 [2] Fun fact: As the program happens only deal with positive numbers, the
 author could have just inserted an int-to-float cast, sidestepping the issue
 altogether. All the other language implementations have the floor() call
 too, though, so it doesn't matter for this discussion.
Totally agree. Maintaining commitment to deprecated hardware which could be removed from the silicone at any time is a bit of a problem looking forwards. Regardless of the decision about whether overloads are created, at very least, I'd suggest x64 should define real as double, since the x87 is deprecated, and x64 ABI uses the SSE unit. It makes no sense at all to use real under any general circumstances in x64 builds. And aside from that, if you *think* you need real for precision, the truth is, you probably have bigger problems. Double already has massive precision. I find it's extremely rare to have precision problems even with float under most normal usage circumstances, assuming you are conscious of the relative magnitudes of your terms.
Jun 27 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 27 June 2014 at 10:51:05 UTC, Manu via Digitalmars-d 
wrote:
 On 27 June 2014 11:31, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause a 
 huge
 performance problem in typical floating point graphics code. 
 An instance of
 this has recently been discussed here in the "Perlin noise 
 benchmark speed"
 thread [1], where even LDC, which already beat DMD by a factor 
 of two,
 generated code more than twice as slow as that by Clang and 
 GCC. Here, the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, 
 the biggest
 problem is the fact that std.math almost exclusively uses 
 reals in its API.
 When working with single- or double-precision floating point 
 numbers, this
 is not only more data to shuffle around than necessary, but on 
 x86_64
 requires the caller to transfer the arguments from the SSE 
 registers onto
 the x87 stack and then convert the result back again. Needless 
 to say, this
 is a serious performance hazard. In fact, this accounts for an 
 1.9x slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads 
 (at the very
 least the double ones) for all of the commonly used functions 
 in std.math.
 This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls effectively 
 widen the
 calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without 
 context, of
 course.

 What do you think?

 Cheers,
 David


 [1] http://forum.dlang.org/thread/lo19l7$n2a$1 digitalmars.com
 [2] Fun fact: As the program happens only deal with positive 
 numbers, the
 author could have just inserted an int-to-float cast, 
 sidestepping the issue
 altogether. All the other language implementations have the 
 floor() call
 too, though, so it doesn't matter for this discussion.
Totally agree. Maintaining commitment to deprecated hardware which could be removed from the silicone at any time is a bit of a problem looking forwards. Regardless of the decision about whether overloads are created, at very least, I'd suggest x64 should define real as double, since the x87 is deprecated, and x64 ABI uses the SSE unit. It makes no sense at all to use real under any general circumstances in x64 builds. And aside from that, if you *think* you need real for precision, the truth is, you probably have bigger problems. Double already has massive precision. I find it's extremely rare to have precision problems even with float under most normal usage circumstances, assuming you are conscious of the relative magnitudes of your terms.
I think real should stay how it is, as the largest hardware-supported floating point type on a system. What needs to change is dmd and phobos' default usage of real. Double should be the standard. People should be able to reach for real if they really need it, but normal D code should target the sweet spot that is double*. I understand why the current situation exists. In 2000 x87 was the standard and the 80bit precision came for free. *The number of algorithms that are both numerically stable/correct and benefit significantly from > 64bit doubles is very small. The same can't be said for 32bit floats.
Jun 27 2014
next sibling parent "Remo" <remo4d gmail.com> writes:
On Friday, 27 June 2014 at 11:10:57 UTC, John Colvin wrote:
 On Friday, 27 June 2014 at 10:51:05 UTC, Manu via Digitalmars-d 
 wrote:
 On 27 June 2014 11:31, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause 
 a huge
 performance problem in typical floating point graphics code. 
 An instance of
 this has recently been discussed here in the "Perlin noise 
 benchmark speed"
 thread [1], where even LDC, which already beat DMD by a 
 factor of two,
 generated code more than twice as slow as that by Clang and 
 GCC. Here, the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, 
 the biggest
 problem is the fact that std.math almost exclusively uses 
 reals in its API.
 When working with single- or double-precision floating point 
 numbers, this
 is not only more data to shuffle around than necessary, but 
 on x86_64
 requires the caller to transfer the arguments from the SSE 
 registers onto
 the x87 stack and then convert the result back again. 
 Needless to say, this
 is a serious performance hazard. In fact, this accounts for 
 an 1.9x slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads 
 (at the very
 least the double ones) for all of the commonly used functions 
 in std.math.
 This is unlikely to break much code, but:
 a) Somebody could rely on the fact that the calls effectively 
 widen the
 calculation to 80 bits on x86 when using type deduction.
 b) Additional overloads make e.g. "&floor" ambiguous without 
 context, of
 course.

 What do you think?

 Cheers,
 David


 [1] http://forum.dlang.org/thread/lo19l7$n2a$1 digitalmars.com
 [2] Fun fact: As the program happens only deal with positive 
 numbers, the
 author could have just inserted an int-to-float cast, 
 sidestepping the issue
 altogether. All the other language implementations have the 
 floor() call
 too, though, so it doesn't matter for this discussion.
Totally agree. Maintaining commitment to deprecated hardware which could be removed from the silicone at any time is a bit of a problem looking forwards. Regardless of the decision about whether overloads are created, at very least, I'd suggest x64 should define real as double, since the x87 is deprecated, and x64 ABI uses the SSE unit. It makes no sense at all to use real under any general circumstances in x64 builds. And aside from that, if you *think* you need real for precision, the truth is, you probably have bigger problems. Double already has massive precision. I find it's extremely rare to have precision problems even with float under most normal usage circumstances, assuming you are conscious of the relative magnitudes of your terms.
I think real should stay how it is, as the largest hardware-supported floating point type on a system. What needs to change is dmd and phobos' default usage of real. Double should be the standard. People should be able to reach for real if they really need it, but normal D code should target the sweet spot that is double*. I understand why the current situation exists. In 2000 x87 was the standard and the 80bit precision came for free. *The number of algorithms that are both numerically stable/correct and benefit significantly from > 64bit doubles is very small. The same can't be said for 32bit floats.
Totally agree! Please add float and double overloads and make double default. Sometimes float is just enough, but in most times double should be used. If some one need more precision as double can provide then 80bit will probably be not enough any way. IMHO intrinsics should be used as default if possible.
Jun 27 2014
prev sibling next sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, 2014-06-27 at 11:10 +0000, John Colvin via Digitalmars-d wrote:
[…]
 I understand why the current situation exists. In 2000 x87 was 
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for decades. All this namby-pamby 80-bit stuff is just an aberration and should never have happened. […] -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 27 2014
parent reply dennis luehring <dl.soluz gmx.net> writes:
Am 27.06.2014 14:20, schrieb Russel Winder via Digitalmars-d:
 On Fri, 2014-06-27 at 11:10 +0000, John Colvin via Digitalmars-d wrote:
 […]
 I understand why the current situation exists. In 2000 x87 was
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for decades. All this namby-pamby 80-bit stuff is just an aberration and should never have happened.
what consumer hardware and compiler supports 128-bit floating points?
Jun 27 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 27 June 2014 at 13:04:31 UTC, dennis luehring wrote:
 Am 27.06.2014 14:20, schrieb Russel Winder via Digitalmars-d:
 On Fri, 2014-06-27 at 11:10 +0000, John Colvin via 
 Digitalmars-d wrote:
 [
]
 I understand why the current situation exists. In 2000 x87 was
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for decades. All this namby-pamby 80-bit stuff is just an aberration and should never have happened.
what consumer hardware and compiler supports 128-bit floating points?
I think he was joking :) No consumer hardware supports IEEE binary128 as far as I know. Wikipedia suggests that Sparc used to have some support.
Jun 27 2014
parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, 2014-06-27 at 13:11 +0000, John Colvin via Digitalmars-d wrote:
 On Friday, 27 June 2014 at 13:04:31 UTC, dennis luehring wrote:
 Am 27.06.2014 14:20, schrieb Russel Winder via Digitalmars-d:
 On Fri, 2014-06-27 at 11:10 +0000, John Colvin via=20
 Digitalmars-d wrote:
 [=C3=A2=C2=80=C5=A0]
 I understand why the current situation exists. In 2000 x87 was
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for=20 decades. All this namby-pamby 80-bit stuff is just an aberration and should=20 never have happened.
what consumer hardware and compiler supports 128-bit floating=20 points?
=20 I think he was joking :)
Actually no, but=E2=80=A6
 No consumer hardware supports IEEE binary128 as far as I know.=20
 Wikipedia suggests that Sparc used to have some support.
For once Wikipedia is not wrong. IBM 128-bit is not IEEE compliant (but pre-dates IEEE standards). SPARC is IEEE compliant. No other hardware manufacturer appears to care about accuracy of floating point expression evaluation. GPU manufacturers have an excuse of sorts in that speed is more important than accuracy for graphics model evaluation. GPGPU suffers because of this. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 28 2014
prev sibling next sibling parent reply Element 126 <dlang.element126 gmail.com> writes:
On 06/27/2014 03:04 PM, dennis luehring wrote:
 Am 27.06.2014 14:20, schrieb Russel Winder via Digitalmars-d:
 On Fri, 2014-06-27 at 11:10 +0000, John Colvin via Digitalmars-d wrote:
 [
]
 I understand why the current situation exists. In 2000 x87 was
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for decades. All this namby-pamby 80-bit stuff is just an aberration and should never have happened.
what consumer hardware and compiler supports 128-bit floating points?
I noticed that std.math mentions partial support for big endian non-IEEE doubledouble. I first thought that it was a software implemetation like the QD library [1][2][3], but I could not find how to use it on x86_64. It looks like it is only available for the PowerPC architecture. Does anyone know about it ? [1] http://crd-legacy.lbl.gov/~dhbailey/mpdist/ [2] http://web.mit.edu/tabbott/Public/quaddouble-debian/qd-2.3.4-old/docs/qd.pdf [3] www.davidhbailey.com/dhbpapers/quad-double.pdf
Jun 27 2014
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 27 June 2014 14:24, Element 126 via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 06/27/2014 03:04 PM, dennis luehring wrote:
 Am 27.06.2014 14:20, schrieb Russel Winder via Digitalmars-d:
 On Fri, 2014-06-27 at 11:10 +0000, John Colvin via Digitalmars-d wrote:
 [ ]
 I understand why the current situation exists. In 2000 x87 was
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for decades. All this namby-pamby 80-bit stuff is just an aberration and should never have happened.
what consumer hardware and compiler supports 128-bit floating points?
I noticed that std.math mentions partial support for big endian non-IEEE doubledouble. I first thought that it was a software implemetation like the QD library [1][2][3], but I could not find how to use it on x86_64. It looks like it is only available for the PowerPC architecture. Does anyone know about it ?
We only support native types in std.math. And partial support is saying more than what there actually is. :-)
Jun 27 2014
parent reply "Kai Nacke" <kai redstar.de> writes:
On Friday, 27 June 2014 at 13:50:29 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 On 27 June 2014 14:24, Element 126 via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 06/27/2014 03:04 PM, dennis luehring wrote:
 Am 27.06.2014 14:20, schrieb Russel Winder via Digitalmars-d:
 On Fri, 2014-06-27 at 11:10 +0000, John Colvin via 
 Digitalmars-d wrote:
 [ ]
 I understand why the current situation exists. In 2000 x87 
 was
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for decades. All this namby-pamby 80-bit stuff is just an aberration and should never have happened.
what consumer hardware and compiler supports 128-bit floating points?
I noticed that std.math mentions partial support for big endian non-IEEE doubledouble. I first thought that it was a software implemetation like the QD library [1][2][3], but I could not find how to use it on x86_64. It looks like it is only available for the PowerPC architecture. Does anyone know about it ?
We only support native types in std.math. And partial support is saying more than what there actually is. :-)
The doubledouble type is available for PowerPC. In fact, I try to use this for my PowerPC64 port of LDC. The partial support here is a bit annoying but I did not find the time to implement the missing functions myself. It is "native" in the sense that it is a supported type by gcc and xlc. Regards, Kai
Jun 27 2014
parent reply "Kagamin" <spam here.lot> writes:
On Friday, 27 June 2014 at 14:50:14 UTC, Kai Nacke wrote:
 The doubledouble type is available for PowerPC. In fact, I try 
 to use this for my PowerPC64 port of LDC. The partial support 
 here is a bit annoying but I did not find the time to implement 
 the missing functions myself.

 It is "native" in the sense that it is a supported type by gcc 
 and xlc.
Doesn't SSE2 effectively operate on double doubles too with instructions like addpd (and others *pd)?
Jun 27 2014
parent Element 126 <dlang.element126 gmail.com> writes:
On 06/27/2014 08:19 PM, Kagamin wrote:
 On Friday, 27 June 2014 at 14:50:14 UTC, Kai Nacke wrote:
 The doubledouble type is available for PowerPC. In fact, I try to use
 this for my PowerPC64 port of LDC. The partial support here is a bit
 annoying but I did not find the time to implement the missing
 functions myself.

 It is "native" in the sense that it is a supported type by gcc and xlc.
Doesn't SSE2 effectively operate on double doubles too with instructions like addpd (and others *pd)?
I'm everything but an assembly guru (so please correct me if I'm wrong), but if my understanding is right, SSE2 only operates element-wise (at least for the operations you are mentionning). For instance, if you operate on two "double2" vectors (in pseudo-code) : element of c only depends on the first elements of a and b. The idea of double-double is that you operate on two doubles in such a way that if you "concatenate" the mantissas of both, then you effectively obtain the correct mathematical semantics of a quadruple precision floating point number, with a higher number of significant digits (~31 vs ~16 for double, in base 10). I am not 100% sure yet, but I think that the idea is to simulate a floating point number with a 106 bit mantissa and a 12 bit exponent as x = s * ( m1 + m2 * 2^(-53) ) * 2^(e-b) = s * m1 * 2^(e-b) + s * m2 * 2^(e-b-53) where s is the sign bit (the same for both doubles), m1 and m2 the mantissas (including the implied 1 for normalized numbers), e the base-2 exponent, b the common bias and 53 an extra bias for the low-order bits (I'm ignoring the denormalized numbers and the special values). The mantissa m1 of the first double gives the first 53 significant bits, and this of the second (m2) the extra 53 bits. The addition is quite straightforward, but it gets tricky when implementing the other operations. The articles I mentionned in my previous post describe these operations for "quadruple-doubles", achieving a ~62 digit precision (implemented in the QD library, but there is also a CUDA implemetation). It is completely overkill for most applications, but it can be useful for studying the convergence of numerical algorithms, and double-doubles can provide the extra precision needed in some simulations (or to compare the results with double precision). It is also a comparatively faster alternative to arbitrary-precision floating-point libraries like GMP/MPFR, since it does not need to emulate every single digit, but instead takes advantage of the native double precision instructions. The downside is that you cannot get more significant bits than n*53, which is not suitable for computing the decimals of pi for instance. To give you more details, I will need to study these papers more thoroughly. I am actually considering bringing double-double and quad-double software support to D, either by making a binding to QD, porting it or starting from scratch based on the papers. I don't know if it will succeed but it will be an interesting exercise anyway. I don't have a lot of time right now but I will try to start working on it in a few weeks. I'd really like to be able to use it with D. Having to rewrite an algorithm in C++ where I could only change one template argument in the main() can be quite painful :-)
Jun 27 2014
prev sibling parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, 2014-06-27 at 15:04 +0200, dennis luehring via Digitalmars-d
wrote:
 Am 27.06.2014 14:20, schrieb Russel Winder via Digitalmars-d:
 On Fri, 2014-06-27 at 11:10 +0000, John Colvin via Digitalmars-d wrote:
 [=C3=A2=C2=80=C5=A0]
 I understand why the current situation exists. In 2000 x87 was
 the standard and the 80bit precision came for free.
Real programmers have been using 128-bit floating point for decades. Al=
l
 this namby-pamby 80-bit stuff is just an aberration and should never
 have happened.
=20 what consumer hardware and compiler supports 128-bit floating points?
None but what has that do do with the core problem being debated? The core problem here is that no programming language has a proper type system able to deal with hardware. C has a hack, Fortran as a less problematic hack. Go insists on float32, float64, etc. which is better but still not great. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 28 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically stable/correct and benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Jun 27 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/27/2014 10:18 PM, Walter Bright wrote:
 On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically stable/correct and benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Sorry for being so abrupt. FP is important to me - it's not just about performance, it's also about accuracy.
Jun 27 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Saturday, 28 June 2014 at 06:16:51 UTC, Walter Bright wrote:
 On 6/27/2014 10:18 PM, Walter Bright wrote:
 On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically 
 stable/correct and benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Sorry for being so abrupt. FP is important to me - it's not just about performance, it's also about accuracy.
I still maintain that the need for the precision of 80bit reals is a niche demand. Its a very important niche, but it doesn't justify having its relatively extreme requirements be the default. Someone writing a matrix inversion has only themselves to blame if they don't know plenty of numerical analysis and look very carefully at the specifications of all operations they are using. Paying the cost of moving to/from the fpu, missing out on increasingly large SIMD units, these make everyone pay the price. inclusion of the 'real' type in D was a great idea, but std.math should be overloaded for float/double/real so people have the choice where they stand on the performance/precision front.
Jun 28 2014
next sibling parent reply "francesco cattoglio" <francesco.cattoglio gmail.com> writes:
On Saturday, 28 June 2014 at 09:07:17 UTC, John Colvin wrote:
 On Saturday, 28 June 2014 at 06:16:51 UTC, Walter Bright wrote:
 On 6/27/2014 10:18 PM, Walter Bright wrote:
 On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically 
 stable/correct and benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Sorry for being so abrupt. FP is important to me - it's not just about performance, it's also about accuracy.
When you need accuracy, 999 times out of 1000 you change the numerical technique, you don't just blindly upgrade the precision. The only real reason one would use 80 bits is when there is an actual need of adding values which differ for more than 16 orders of magnitude. And I've never seen this happen in any numerical paper I've read.
 I still maintain that the need for the precision of 80bit reals 
 is a niche demand. Its a very important niche, but it doesn't 
 justify having its relatively extreme requirements be the 
 default. Someone writing a matrix inversion has only themselves 
 to blame if they don't know plenty of numerical analysis and 
 look very carefully at the specifications of all operations 
 they are using.
Couldn't agree more. 80 bit IS a niche, which is really nice to have, but shouldn't be the standard if we lose on performance.
 Paying the cost of moving to/from the fpu, missing out on 
 increasingly large SIMD units, these make everyone pay the 
 price.
Especially the numerical analysts themselves will pay that price. 64 bit HAS to be as fast as possible, if you want to be competitive when it comes to any kind of numerical work.
Jun 28 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 2:47 AM, francesco cattoglio wrote:
 When you need accuracy, 999 times out of 1000 you change the numerical
 technique, you don't just blindly upgrade the precision.
I have experience doing numerical work? Upgrading the precision is the first thing people try.
 The only real reason one would use 80 bits is when there is an actual need of
 adding values which differ for more than 16 orders of magnitude. And I've never
 seen this happen in any numerical paper I've read.
It happens with both numerical integration and inverting matrices. Inverting matrices is commonplace for solving N equations with N unknowns. Errors accumulate very rapidly and easily overwhelm the significance of the answer.
 Especially the numerical analysts themselves will pay that price. 64 bit HAS to
 be as fast as possible, if you want to be competitive when it comes to any kind
 of numerical work.
Getting the wrong answer quickly is not useful when you're calculating the stress levels in a part. Again, I've done numerical programming in airframe design. The correct answer is what matters. You can accept wrong answers in graphics display algorithms, but not when designing critical parts.
Jun 28 2014
next sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 2014-06-28 at 03:42 -0700, Walter Bright via Digitalmars-d
wrote:
 On 6/28/2014 2:47 AM, francesco cattoglio wrote:
 When you need accuracy, 999 times out of 1000 you change the numerical
 technique, you don't just blindly upgrade the precision.
=20 I have experience doing numerical work? Upgrading the precision is the fi=
rst=20
 thing people try.
Nonetheless, algorithm and expression of algorithm are often more important. As proven by my Pi_Quadrature examples you can appear to have better results with greater precision, but actually the way the code operates is actually the core problem: the code I have written does not do things in the best way to achieve the best result as a given accuracy level.. [=E2=80=A6]
=20
 Errors accumulate very rapidly and easily overwhelm the significance of t=
he answer. I wonder if programmers should only be allowed to use floating point number sin their code if they have studied numerical analysis?
=20
 Especially the numerical analysts themselves will pay that price. 64 bi=
t HAS to
 be as fast as possible, if you want to be competitive when it comes to =
any kind
 of numerical work.
=20 Getting the wrong answer quickly is not useful when you're calculating th=
e=20
 stress levels in a part.
[=E2=80=A6]
 Again, I've done numerical programming in airframe design. The correct an=
swer is=20
 what matters. You can accept wrong answers in graphics display algorithms=
, but=20
 not when designing critical parts.
Or indeed when calculating anything to do with money. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 28 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
 I wonder if programmers should only be allowed to use floating point
 number sin their code if they have studied numerical analysis?
Be that as it may, why should a programming language make it harder for them to get right than necessary? The first rule in doing numerical calculations, hammered into me at Caltech, is use the max precision available at every step. Rounding error is a major problem, and is very underappreciated by engineers until they have a big screwup. The idea that "64 fp bits ought to be enough for anybody" is a pernicious disaster, to put it mildly.
 Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
Jun 28 2014
next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via Digitalmars-d wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents). T -- The best compiler is between your ears. -- Michael Abrash
Jun 28 2014
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 29 June 2014 at 04:38:31 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via 
 Digitalmars-d wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents). T
MtGox was using float.
Jun 28 2014
parent "Paolo Invernizzi" <paolo.invernizzi no.address> writes:
On Sunday, 29 June 2014 at 04:46:49 UTC, deadalnix wrote:
 On Sunday, 29 June 2014 at 04:38:31 UTC, H. S. Teoh via 
 Digitalmars-d wrote:
 On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via 
 Digitalmars-d wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents). T
MtGox was using float.
LOL ;-) --- Paolo
Jun 29 2014
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 9:36 PM, H. S. Teoh via Digitalmars-d wrote:
 On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via Digitalmars-d
wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
 Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents).
I think that's what I said :-)
Jun 28 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/28/14, 9:36 PM, H. S. Teoh via Digitalmars-d wrote:
 On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via Digitalmars-d
wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
 Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents).
A friend who works at a hedge fund (after making the rounds to the NYC large financial companies) told me that's a myth. Any nontrivial calculation involving money (interest, fixed income, derivatives, ...) needs floating point. He never needed more than double. Andrei
Jun 29 2014
next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 29 June 2014 15:59, Andrei Alexandrescu via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 6/28/14, 9:36 PM, H. S. Teoh via Digitalmars-d wrote:
 On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via Digitalmars-d
 wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
 Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents).
A friend who works at a hedge fund (after making the rounds to the NYC large financial companies) told me that's a myth. Any nontrivial calculation involving money (interest, fixed income, derivatives, ...) needs floating point. He never needed more than double. Andrei
I would have thought money would use fixed point decimal floats. Iain
Jun 29 2014
next sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Sunday, 29 June 2014 at 15:51:03 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 I would have thought money would use fixed point […] floats.
Huh? ;) David
Jun 29 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/29/14, 8:50 AM, Iain Buclaw via Digitalmars-d wrote:
 On 29 June 2014 15:59, Andrei Alexandrescu via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 6/28/14, 9:36 PM, H. S. Teoh via Digitalmars-d wrote:
 On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via Digitalmars-d
 wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
 Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents).
A friend who works at a hedge fund (after making the rounds to the NYC large financial companies) told me that's a myth. Any nontrivial calculation involving money (interest, fixed income, derivatives, ...) needs floating point. He never needed more than double. Andrei
I would have thought money would use fixed point decimal floats.
And what meaningful computation can you do with such? Using fixed point for money would be like the guy in Walter's story rounding to two decimals after each step in the calculation. Even for a matter as simple as average price for a share bought in multiple batches you need floating point. Andrei
Jun 29 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 9:54 AM, Andrei Alexandrescu wrote:
 On 6/29/14, 8:50 AM, Iain Buclaw via Digitalmars-d wrote:
 On 29 June 2014 15:59, Andrei Alexandrescu via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On 6/28/14, 9:36 PM, H. S. Teoh via Digitalmars-d wrote:
 On Sat, Jun 28, 2014 at 05:16:53PM -0700, Walter Bright via Digitalmars-d
 wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:
[...]
 Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
For counting money, I heard that the recommendation is to use fixed-point arithmetic (i.e. integer values in cents).
A friend who works at a hedge fund (after making the rounds to the NYC large financial companies) told me that's a myth. Any nontrivial calculation involving money (interest, fixed income, derivatives, ...) needs floating point. He never needed more than double. Andrei
I would have thought money would use fixed point decimal floats.
And what meaningful computation can you do with such? Using fixed point for money would be like the guy in Walter's story rounding to two decimals after each step in the calculation. Even for a matter as simple as average price for a share bought in multiple batches you need floating point.
I can see using floating point for the calculation, but the final result should be stored as whole pennies.
Jun 29 2014
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 2014-06-29 at 07:59 -0700, Andrei Alexandrescu via Digitalmars-d
wrote:
[…]

 A friend who works at a hedge fund (after making the rounds to the NYC 
 large financial companies) told me that's a myth. Any nontrivial 
 calculation involving money (interest, fixed income, derivatives, ...) 
 needs floating point. He never needed more than double.
Very definitely so. Fixed point or integer arithmetic for simple "household" finance fair enough, but for "finance house" calculations you generally need 22+ significant denary digits to meet with compliance requirements. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 29 2014
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 11:13 AM, Russel Winder via Digitalmars-d wrote:
 On Sun, 2014-06-29 at 07:59 -0700, Andrei Alexandrescu via Digitalmars-d
 wrote:
 […]

 A friend who works at a hedge fund (after making the rounds to the NYC
 large financial companies) told me that's a myth. Any nontrivial
 calculation involving money (interest, fixed income, derivatives, ...)
 needs floating point. He never needed more than double.
Very definitely so. Fixed point or integer arithmetic for simple "household" finance fair enough, but for "finance house" calculations you generally need 22+ significant denary digits to meet with compliance requirements.
Doubles are only good to 17 digits, and even that 17th digit is flaky.
Jun 29 2014
next sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Sunday, 29 June 2014 at 19:18:49 UTC, Walter Bright wrote:
 On 6/29/2014 11:13 AM, Russel Winder via Digitalmars-d wrote:
 Very definitely so. Fixed point or integer arithmetic for 
 simple
 "household" finance fair enough, but for "finance house" 
 calculations
 you generally need 22+ significant denary digits to meet with 
 compliance
 requirements.
Doubles are only good to 17 digits, and even that 17th digit is flaky.
The 11 extra bits in an x87 real wouldn't get you to 22 either, though. ;) David
Jun 29 2014
prev sibling parent Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 2014-06-29 at 12:18 -0700, Walter Bright via Digitalmars-d
wrote:
[=E2=80=A6]
 Doubles are only good to 17 digits, and even that 17th digit is flaky.
Hence the use of software "real" numbers becoming the norm for calculating these bioinformatics and quant models. (I rarely see better that 14 or 15 denary digits of accuracy for 64-bit fp hardware. :-( --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 29 2014
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/29/14, 11:13 AM, Russel Winder via Digitalmars-d wrote:
 On Sun, 2014-06-29 at 07:59 -0700, Andrei Alexandrescu via Digitalmars-d
 wrote:
 […]

 A friend who works at a hedge fund (after making the rounds to the NYC
 large financial companies) told me that's a myth. Any nontrivial
 calculation involving money (interest, fixed income, derivatives, ...)
 needs floating point. He never needed more than double.
Very definitely so. Fixed point or integer arithmetic for simple "household" finance fair enough, but for "finance house" calculations you generally need 22+ significant denary digits to meet with compliance requirements.
I don't know of US regulations that ask for such. What I do know is I gave my hedge fund friend a call (today is his name day so it was as good a pretext as any) and mentioned that some people believe fixed point is used in finance. His answer was: BWAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAAAAAAAAAAAAAAAAAAAAAAA! I asked about how they solve accumulating numeric errors and he said it's on a case basis. Most of the time it's pennies for billions of dollars, so nobody cares. Sometimes there are reconciliations needed - so called REC's - that compare and adjust outputs of different algorithms. One nice war story he recalled: someone was storing the number of seconds as a double, and truncate it to int where needed. An error of at most one second wasn't important in the context. However, sometimes the second was around midnight so an error of one second was an error of one day, which was significant. The solution was to use rounding instead of truncation. Andrei
Jun 29 2014
prev sibling parent reply "Don" <x nospam.com> writes:
On Sunday, 29 June 2014 at 18:13:59 UTC, Russel Winder via 
Digitalmars-d wrote:
 On Sun, 2014-06-29 at 07:59 -0700, Andrei Alexandrescu via 
 Digitalmars-d
 wrote:
 […]

 A friend who works at a hedge fund (after making the rounds to 
 the NYC large financial companies) told me that's a myth. Any 
 nontrivial calculation involving money (interest, fixed 
 income, derivatives, ...) needs floating point. He never 
 needed more than double.
Very definitely so. Fixed point or integer arithmetic for simple "household" finance fair enough, but for "finance house" calculations you generally need 22+ significant denary digits to meet with compliance requirements.
Many people seem to have the bizarre idea that floating point is less accurate than integer arithmetic. As if storing a value into a double makes it instantly "fuzzy", or something. In fact, providing that the the precision is large enough, every operation that is exact in integers, is exact in floating point as well. And if you perform a division using integers, you've silently lost precision. So I'm not sure what benefit you'd gain by eschewing floating point.
Jun 30 2014
next sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 30 June 2014 at 11:57:04 UTC, Don wrote:
 And if you perform a division using integers, you've silently 
 lost precision.
2 ints of arbitrary length = rational numbers => no loss of precision for divs. CPU vendors make arbitrary decisions about FP and break compliance with no remorse for single precision float vector operations in order to reduce die size / increase throughput. That includes not having NaN/Inf, reducing mantissa precision for some operations, etc. FP is not portable out-of-the-box. I think the main advantage of integers is that you control the precision and can repeat the calculation with the same result. It is easier to avoid stability issues with integers too. And it is portable.
Jun 30 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 4:57 AM, Don wrote:
 Many people seem to have the bizarre idea that floating point is less accurate
 than integer arithmetic. As if storing a value into a double makes it instantly
 "fuzzy", or something.
 In fact, providing that the the precision is large enough, every operation that
 is exact in integers, is exact in floating point as well.
 And if you perform a division using integers, you've silently lost precision.
 So I'm not sure what benefit you'd gain by eschewing floating point.
1. 64 bit longs have more precision than 64 bit doubles. 2. My business accounts have no notion of fractional cents, so there's no reason to confuse the bookkeeping with them. I understand that for purposes of calculating interest, you'd definitely want the intermediate answers to be in floating point. But when posting to an account, you want cents. And these days, dealing with trillions of dollars, one is getting awfully close to the max precision of doubles :-)
Jun 30 2014
next sibling parent reply "Sean Kelly" <sean invisibleduck.org> writes:
On Monday, 30 June 2014 at 17:01:07 UTC, Walter Bright wrote:
 1. 64 bit longs have more precision than 64 bit doubles.

 2. My business accounts have no notion of fractional cents, so 
 there's no reason to confuse the bookkeeping with them.

 I understand that for purposes of calculating interest, you'd 
 definitely want the intermediate answers to be in floating 
 point. But when posting to an account, you want cents.
If your liquid assets are represented in dollars, yes. But this is really just a display issue. The amounts could easily be stored in a floating point representation and rounded when reporting is done. This is how all financial systems I've ever worked on have operated (hedge fund accounting systems, trading systems, and enterprise-level accounting systems used by companies like Goldman Sachs), though every once in a while you might encounter one that uses the SQL "money" type for certain types of accounting.
 And these days, dealing with trillions of dollars, one is 
 getting awfully close to the max precision of doubles :-)
To be fair, most accounts don't contain trillions of dollars, or report on aggregate sums of that magnitude. That's still well within the realm of special purpose software. And for that I'd likely be using quads and just live with the performance hit.
Jun 30 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 11:10 AM, Sean Kelly wrote:
 If your liquid assets are represented in dollars, yes.  But this
 is really just a display issue.  The amounts could easily be
 stored in a floating point representation and rounded when
 reporting is done.
But if you round only for display purposes (and for sending statements to a customer), the customer can easily wind up with accounts that don't balance to the penny.
Jun 30 2014
parent "Sean Kelly" <sean invisibleduck.org> writes:
On Monday, 30 June 2014 at 19:15:44 UTC, Walter Bright wrote:
 On 6/30/2014 11:10 AM, Sean Kelly wrote:
 If your liquid assets are represented in dollars, yes.  But 
 this
 is really just a display issue.  The amounts could easily be
 stored in a floating point representation and rounded when
 reporting is done.
But if you round only for display purposes (and for sending statements to a customer), the customer can easily wind up with accounts that don't balance to the penny.
And in those cases, rounding occurs at the proper points to ensure that things match whatever on-paper accounting you might have done. "Reporting" in this instance may actually mean writing data to a ledger somewhere. My point was that effectively all of the math that's done in these systems is floating-point. The fixed-point conversions occur at serialization points.
Jun 30 2014
prev sibling parent "JR" <zorael gmail.com> writes:
On Monday, 30 June 2014 at 17:01:07 UTC, Walter Bright wrote:
 2. My business accounts have no notion of fractional cents, so 
 there's no reason to confuse the bookkeeping with them.
.00001 BTC
Jun 30 2014
prev sibling parent "Sean Kelly" <sean invisibleduck.org> writes:
On Sunday, 29 June 2014 at 00:16:51 UTC, Walter Bright wrote:
 On 6/28/2014 3:57 AM, Russel Winder via Digitalmars-d wrote:

 Or indeed when calculating anything to do with money.
You're better off using 64 bit longs counting cents to represent money than using floating point. But yeah, counting money has its own special problems.
Maybe if by "money" you mean dollars in the bank. But for anything much beyond that you're doing floating point math. Often with specific rules for how and when rounding should occur. Perhaps interestingly, it's typical for hedge funds to have a "rounding partner" who receives all the fractional pennies that are lost when divvying up the income for the other investors.
Jun 28 2014
prev sibling next sibling parent reply "francesco cattoglio" <francesco.cattoglio gmail.com> writes:
On Saturday, 28 June 2014 at 10:42:19 UTC, Walter Bright wrote:
 On 6/28/2014 2:47 AM, francesco cattoglio wrote:
 I have experience doing numerical work? Upgrading the precision 
 is the first thing people try.
Brute force is always the first thing people try :o)
 It happens with both numerical integration and inverting 
 matrices. Inverting matrices is commonplace for solving N 
 equations with N unknowns.
 Errors accumulate very rapidly and easily overwhelm the 
 significance of the answer.
And that's exactly the reason you change approach instead of getting greater precision: the "adding precision" approach scales horribly, at least in my field of study, which is solving numerical PDEs. (BTW: no sane person inverts matrices)
 Getting the wrong answer quickly is not useful when you're 
 calculating the stress levels in a part.
We are talking about paying a price when you don't need it. With the correct approach, solving numerical problems with double precision floats yelds perfectly fine results. And it is, in fact, commonplace. Again, I've not read yet a research paper in which it was clearly stated that 64bit floats were not good enough for solving a whole class of PDE problem. I'm not saying that real is useless, quite the opposite: I love the idea of having an extra tool when the need arises. I think the focus should be about not paying a price for what you don't use
Jun 28 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 4:27 AM, francesco cattoglio wrote:
 We are talking about paying a price when you don't need it.
More than that - the suggestion has come up here (and comes up repeatedly) to completely remove support for 80 bits. Heck, Microsoft has done so with VC++ and even once attempted to completely remove it from 64 bit Windows (I talked them out of it, you can thank me!).
 With the correct
 approach, solving numerical problems with double precision floats yelds
 perfectly fine results. And it is, in fact, commonplace.
Presuming your average mechanical engineer is well versed in how to do matrix inversion while accounting for precision problems is an absurd pipe dream. Most engineers only know their math book algorithms, not comp sci best practices. Heck, few CS graduates know how to do it.
 Again, I've not read yet a research paper in which it was clearly stated that
 64bit floats were not good enough for solving a whole class of PDE problem. I'm
 not saying that real is useless, quite the opposite: I love the idea of having
 an extra tool when the need arises. I think the focus should be about not
paying
 a price for what you don't use
I used to work doing numerical analysis on airplane parts. I didn't need a research paper to discover how much precision matters and when my results fell apart.
Jun 28 2014
parent reply "francesco cattoglio" <francesco.cattoglio gmail.com> writes:
On Sunday, 29 June 2014 at 00:22:02 UTC, Walter Bright wrote:
 On 6/28/2014 4:27 AM, francesco cattoglio wrote:
 We are talking about paying a price when you don't need it.
More than that - the suggestion has come up here (and comes up repeatedly) to completely remove support for 80 bits. Heck, Microsoft has done so with VC++ and even once attempted to completely remove it from 64 bit Windows (I talked them out of it, you can thank me!).
Then I must have missed the post. Removing 80 bit support would sound like madness to my ears. And about that Microsoft thing, thanks a lot :o)
Jun 29 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 12:57 AM, francesco cattoglio wrote:
 And about that Microsoft thing, thanks a lot :o)
Welcs!
Jun 29 2014
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/28/14, 3:42 AM, Walter Bright wrote:
 Inverting matrices is commonplace for solving N equations with N
 unknowns.
Actually nobody does that. Also, one consideration is that the focus of numeric work changes with time; nowadays it's all about machine learning, a field that virtually didn't exist 20 years ago. In machine learning precision does make a difference sometimes, but the key to good ML work is to run many iterations over large data sets - i.e., speed. I have an alarm go off when someone proffers a very strong conviction. Very strong convictions means there is no listening to any argument right off the bat, which locks out any reasonable discussion before it even begins. For better or worse modern computing units have focused on 32- and 64-bit float, leaving 80-bit floats neglected. I think it's time to accept that simple fact and act on it, instead of claiming we're the best in the world at FP math while everybody else speeds by. Andrei
Jun 28 2014
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Saturday, 28 June 2014 at 14:01:13 UTC, Andrei Alexandrescu 
wrote:
 On 6/28/14, 3:42 AM, Walter Bright wrote:
 Inverting matrices is commonplace for solving N equations with 
 N
 unknowns.
Actually nobody does that. Also, one consideration is that the focus of numeric work changes with time; nowadays it's all about machine learning
It's the most actively publicised frontier, perhaps, but there's a huge amount of solid work happening elsewhere. People still need better fluid, molecular dynamics etc. simulations, numerical PDE solvers, finite element modelling and so on. There's a whole world out there :) That doesn't diminish your main point though.
 For better or worse modern computing units have focused on 32- 
 and 64-bit float, leaving 80-bit floats neglected. I think it's 
 time to accept that simple fact and act on it, instead of 
 claiming we're the best in the world at FP math while everybody 
 else speeds by.


 Andrei
+1
Jun 28 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 7:01 AM, Andrei Alexandrescu wrote:
 On 6/28/14, 3:42 AM, Walter Bright wrote:
 Inverting matrices is commonplace for solving N equations with N
 unknowns.
Actually nobody does that.
I did that at Boeing when doing analysis of the movement of the control linkages. The traditional way it had been done before was using paper and pencil with drafting tools - I showed how it could be done with matrix math.
 I have an alarm go off when someone proffers a very strong conviction. Very
 strong convictions means there is no listening to any argument right off the
 bat, which locks out any reasonable discussion before it even begins.
So far, everyone here has dismissed my experienced out of hand. You too, with "nobody does that". I don't know how anyone here can make such a statement. How many of us have worked in non-programming engineering shops, besides me?
 For better or worse modern computing units have focused on 32- and 64-bit
float,
 leaving 80-bit floats neglected.
Yep, for the game/graphics industry. Modern computing has also produced crappy trig functions with popular C compilers, because nobody using C cares about accurate answers (or they just assume what they're getting is correct - even worse).
 I think it's time to accept that simple fact
 and act on it, instead of claiming we're the best in the world at FP math while
 everybody else speeds by.
Leaving us with a market opportunity for precision FP. I note that even the title of this thread says nothing about accuracy, nor did the benchmark attempt to assess if there was a difference in results.
Jun 28 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/28/14, 5:33 PM, Walter Bright wrote:
 On 6/28/2014 7:01 AM, Andrei Alexandrescu wrote:
 On 6/28/14, 3:42 AM, Walter Bright wrote:
 Inverting matrices is commonplace for solving N equations with N
 unknowns.
Actually nobody does that.
I did that at Boeing when doing analysis of the movement of the control linkages. The traditional way it had been done before was using paper and pencil with drafting tools - I showed how it could be done with matrix math.
Pen on paper is a low baseline. The classic way to solve linear equations with computers is to use Gaussian elimination methods adjusted to cancel imprecision. (There are a number of more specialized methods.) For really large equations with sparse matrices one uses the method of relaxations.
 I have an alarm go off when someone proffers a very strong conviction.
 Very
 strong convictions means there is no listening to any argument right
 off the
 bat, which locks out any reasonable discussion before it even begins.
So far, everyone here has dismissed my experienced out of hand. You too, with "nobody does that". I don't know how anyone here can make such a statement. How many of us have worked in non-programming engineering shops, besides me?
My thesis - http://erdani.com/research/dissertation_color.pdf - and some of my work at Facebook, which has been patented - http://www.faqs.org/patents/app/20140046959 - use large matrix algebra intensively.
 For better or worse modern computing units have focused on 32- and
 64-bit float,
 leaving 80-bit floats neglected.
Yep, for the game/graphics industry. Modern computing has also produced crappy trig functions with popular C compilers, because nobody using C cares about accurate answers (or they just assume what they're getting is correct - even worse).
 I think it's time to accept that simple fact
 and act on it, instead of claiming we're the best in the world at FP
 math while
 everybody else speeds by.
Leaving us with a market opportunity for precision FP. I note that even the title of this thread says nothing about accuracy, nor did the benchmark attempt to assess if there was a difference in results.
All I'm saying is that our convictions should be informed by, and commensurate with, our expertise. Andrei
Jun 28 2014
prev sibling parent reply "Alex_Dovhal" <alex_dovhal somewhere.com> writes:
On Saturday, 28 June 2014 at 10:42:19 UTC, Walter Bright wrote:
 It happens with both numerical integration and inverting 
 matrices. Inverting matrices is commonplace for solving N 
 equations with N unknowns.

 Errors accumulate very rapidly and easily overwhelm the 
 significance of the answer.
if one wants better precision with solving linear equation he/she at least would use QR-decomposition.
Jun 28 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Sat, Jun 28, 2014 at 03:31:36PM +0000, Alex_Dovhal via Digitalmars-d wrote:
 On Saturday, 28 June 2014 at 10:42:19 UTC, Walter Bright wrote:
It happens with both numerical integration and inverting matrices.
Inverting matrices is commonplace for solving N equations with N
unknowns.

Errors accumulate very rapidly and easily overwhelm the significance
of the answer.
if one wants better precision with solving linear equation he/she at least would use QR-decomposition.
Yeah, inverting matrices is generally not the preferred method for solving linear equations, precisely because of accumulated roundoff errors. Usually one would use a linear algebra library which has dedicated algorithms for solving linear systems, which extracts the solution(s) using more numerically-stable methods than brute-force matrix inversion. They are also more efficient than inverting the matrix and then doing a matrix multiplication to get the solution vector. Mathematically, they are equivalent to matrix inversion, but numerically they are more stable and not as prone to precision loss issues. Having said that, though, added precision is always welcome, particularly when studying mathematical objects (as opposed to more practical applications like engineering, where 6-8 digits of precision in the result is generally more than good enough). Of course, the most ideal implementation would be to use algebraic representations that can represent quantities exactly, but exact representations are not always practical (they are too slow for very large inputs, or existing libraries only support hardware floating-point types, or existing code requires a lot of effort to support software arbitrary-precision floats). In such cases, squeezing as much precision out of your hardware as possible is a good first step towards a solution. T -- Time flies like an arrow. Fruit flies like a banana.
Jun 28 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 11:16 AM, H. S. Teoh via Digitalmars-d wrote:
 (as opposed to more
 practical applications like engineering, where 6-8 digits of precision
 in the result is generally more than good enough).
Of the final result, sure, but NOT for the intermediate results. It is an utter fallacy to conflate required precision of the result with precision of the intermediate results.
Jun 28 2014
prev sibling next sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 2014-06-28 at 09:07 +0000, John Colvin via Digitalmars-d wrote:
[=E2=80=A6]
 I still maintain that the need for the precision of 80bit reals=20
 is a niche demand. Its a very important niche, but it doesn't=20
 justify having its relatively extreme requirements be the=20
 default. Someone writing a matrix inversion has only themselves=20
 to blame if they don't know plenty of numerical analysis and look=20
 very carefully at the specifications of all operations they are=20
 using.
I fear the whole argument is getting misguided. We should reset. If you are doing numerical calculations then accuracy is critical. Arbitrary precision floats are the only real (!) way of doing any numeric non-integer calculation, and arbitrary precision integers are the only way of doing integer calculations. However speed is also an issue, so to obtain speed we have hardware integer and floating point ALUs. The cost for the integer ALU is bounded integers. Python appreciates this and uses hardware integers when it can and software integers otherwise. Thus Python is very good for doing integer work. C, C++, Go, D, Fortran, etc. are fundamentally crap for integer calculation because integers are bounded. Of course if calculations are prvably within the hardware integer bounds this is not a constraint and we are happy with hardware integers. Just don't try calculating factorial, Fibonacci numbers and other numbers used in some bioinformatics and quant models. There is a reason why SciPy has a massive following in bioinformatics and quant comuting. The cost for floating point ALU is accuracy. Hardware floating point numbers are dreadful in that sense, but again the issue is speed and for GPU they went 32-bit for speed. Now they are going 64-bit as they can just about get the same speed and the accuracy is so much greater. For hardware floating point the more bits you have the better. Hence IBM in the 360 and later having 128-bit floating point for accuracy at the expense of some speed. Sun had 128-bit in the SPARC processors for accuracy at the expense of a little speed. As Walter has or will tell us, C (and thus C++) got things woefully wrong in support of numerical work because the inventors were focused on writing operating systems, supporting only PDP hardware. They and the folks that then wrote various algorithms didn't really get numerical analysis. If C had targeted IBM 360 from the outset things might have been better. We have to be clear on this: Fortran is the only language that supports hardware floating types even at all well. Intel's 80-bit floating point were an aberration, they should just have done 128-bit in the first place. OK so they got the 80-bit stuff as a sort of free side-effect of creating 64-bit, but they ran with. They shouldn't have done. I cannot see it ever happening again. cf. ARM. By being focused on Intel chips, D has failed to get floating point correct in avery analogous way to C failing to get floating point types right by focusing on PDP. Yes using 80-bit on Intel is good, but no-one else has this. Floating point sizes should be 32-, 64-, 128-, 256-bit, etc. D needs to be able to handle this. So does C, C++, Java, etc. Go will be able to handle it when it is ported to appropriate hardware as they use float32, float64, etc. as their types. None of this float, double, long double, double double rubbish. So D should perhaps make a breaking change and have types int32, int64, float32, float64, float80, and get away from the vagaries of bizarre type relationships with hardware?=20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 28 2014
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Saturday, 28 June 2014 at 10:34:00 UTC, Russel Winder via 
Digitalmars-d wrote:

 So D should perhaps make a breaking change and have types 
 int32, int64,
 float32, float64, float80, and get away from the vagaries of 
 bizarre
 type relationships with hardware?
`real`* is the only builtin numerical type in D that doesn't have a defined width. http://dlang.org/type.html *well I guess there's size_t and ptrdiff_t, but they aren't distinct types in their own right.
Jun 28 2014
prev sibling next sibling parent reply Element 126 <dlang.element126 gmail.com> writes:
On 06/28/2014 12:33 PM, Russel Winder via Digitalmars-d wrote:
 On Sat, 2014-06-28 at 09:07 +0000, John Colvin via Digitalmars-d wrote:
 […]
 I still maintain that the need for the precision of 80bit reals
 is a niche demand. Its a very important niche, but it doesn't
 justify having its relatively extreme requirements be the
 default. Someone writing a matrix inversion has only themselves
 to blame if they don't know plenty of numerical analysis and look
 very carefully at the specifications of all operations they are
 using.
I fear the whole argument is getting misguided. We should reset. If you are doing numerical calculations then accuracy is critical. Arbitrary precision floats are the only real (!) way of doing any numeric non-integer calculation, and arbitrary precision integers are the only way of doing integer calculations. However speed is also an issue, so to obtain speed we have hardware integer and floating point ALUs. The cost for the integer ALU is bounded integers. Python appreciates this and uses hardware integers when it can and software integers otherwise. Thus Python is very good for doing integer work. C, C++, Go, D, Fortran, etc. are fundamentally crap for integer calculation because integers are bounded. Of course if calculations are prvably within the hardware integer bounds this is not a constraint and we are happy with hardware integers. Just don't try calculating factorial, Fibonacci numbers and other numbers used in some bioinformatics and quant models. There is a reason why SciPy has a massive following in bioinformatics and quant comuting. The cost for floating point ALU is accuracy. Hardware floating point numbers are dreadful in that sense, but again the issue is speed and for GPU they went 32-bit for speed. Now they are going 64-bit as they can just about get the same speed and the accuracy is so much greater. For hardware floating point the more bits you have the better. Hence IBM in the 360 and later having 128-bit floating point for accuracy at the expense of some speed. Sun had 128-bit in the SPARC processors for accuracy at the expense of a little speed. As Walter has or will tell us, C (and thus C++) got things woefully wrong in support of numerical work because the inventors were focused on writing operating systems, supporting only PDP hardware. They and the folks that then wrote various algorithms didn't really get numerical analysis. If C had targeted IBM 360 from the outset things might have been better. We have to be clear on this: Fortran is the only language that supports hardware floating types even at all well. Intel's 80-bit floating point were an aberration, they should just have done 128-bit in the first place. OK so they got the 80-bit stuff as a sort of free side-effect of creating 64-bit, but they ran with. They shouldn't have done. I cannot see it ever happening again. cf. ARM. By being focused on Intel chips, D has failed to get floating point correct in avery analogous way to C failing to get floating point types right by focusing on PDP. Yes using 80-bit on Intel is good, but no-one else has this. Floating point sizes should be 32-, 64-, 128-, 256-bit, etc. D needs to be able to handle this. So does C, C++, Java, etc. Go will be able to handle it when it is ported to appropriate hardware as they use float32, float64, etc. as their types. None of this float, double, long double, double double rubbish. So D should perhaps make a breaking change and have types int32, int64, float32, float64, float80, and get away from the vagaries of bizarre type relationships with hardware?
+1 for float32 & cie. These names are much more explicit than the current ones. But I see two problems with it : - These names are already used in core.simd to denote vectors, and AVX 3 (which should appear in mainstream CPUs next year) will require to use float16, so the next revision might cause a collision. This could be avoided by using real32, real64... instead, but I prefer floatxx since it reminds us that we are not dealing with an exact real number. - These types are redundant, and people coming from C/C++ will likely use float and double instead. It's much too late to think of deprecating them since it would break backward compatibility (although it would be trivial to update the code with "DFix"... if someone is still maintaining the code). A workaround would be to use a template which maps to the correct native type, iff it has the exact number of bits specified, or issues an error. Here is a quick mockup (does not support all types). I used "fp" instead of "float" or "real" to avoid name collisions with the current types. template fp(uint n) { static if (n == 32) { alias fp = float; } else static if (n == 64) { alias fp = double; } else static if (n == 80) { static if (real.mant_dig == 64) { alias fp = real; } else { static assert(false, "No 80 bit floating point type supported on this architecture"); } } else static if (n == 128) { alias fp = quadruple; // Or doubledouble on PPC. Add other static ifs if necessary. } else { import std.conv: to; static assert(false, "No "~to!string(n)~" bit floating point type."); } } void main() { fp!32 x = 3.1415926; assert(is(typeof(x) == float)); fp!64 y = 3.141592653589793; assert(is(typeof(y) == double)); fp!80 z = 3.14159265358979323846; assert(is(typeof(z) == real)); /* Fails on x86_64, as it should, but the error message could be made more explicit. * Currently : "undefined identifier quadruple" * Should ideally be : "No native 128 bit floating-point type supported on x86_64 architecture." */ /* fp!128 w = 3.14159265358979323846264338327950288; assert(is(typeof(w) == quadruple)); */ }
Jun 28 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 5:43 AM, Element 126 wrote:
 +1 for float32 & cie. These names are much more explicit than the current ones.
I don't see any relevance to this discussion with whether 32 bit floats are named 'float' or 'float32'.
Jun 28 2014
parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 2014-06-28 at 17:41 -0700, Walter Bright via Digitalmars-d
wrote:
 On 6/28/2014 5:43 AM, Element 126 wrote:
 +1 for float32 & cie. These names are much more explicit than the current ones.
I don't see any relevance to this discussion with whether 32 bit floats are named 'float' or 'float32'.
This is getting way off the original thread, but… The issue is what hardware representations are supported: what does float mean? This is a Humpty Dumpty situation and "something must be done". Hence Go stops with the undefined words and gives definite global meanings to type names. It would be helpful if D eschewed the C/C++ heritage as well and got more definite about type names. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 29 2014
parent reply "David Nadlinger" <code klickverbot.at> writes:
On Sunday, 29 June 2014 at 18:17:06 UTC, Russel Winder via 
Digitalmars-d wrote:
 This is getting way off the original thread, but…

 The issue is what hardware representations are supported: what 
 does
 float mean? This is a Humpty Dumpty situation and "something 
 must be
 done". Hence Go stops with the undefined words and gives 
 definite global
 meanings to type names. It would be helpful if D eschewed the 
 C/C++
 heritage as well and got more definite about type names.
There is nothing Humpty Dumpty about the current situation. You are simply missing the fact that float and double are already defined as 32 bit/64 bit IEEE 754 compliant floating point numbers in the spec. There is nothing ambiguous about that, just as char/int/long have defined bit-widths in D. David
Jun 29 2014
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 12:02 PM, David Nadlinger wrote:
 On Sunday, 29 June 2014 at 18:17:06 UTC, Russel Winder via Digitalmars-d wrote:
 This is getting way off the original thread, but…

 The issue is what hardware representations are supported: what does
 float mean? This is a Humpty Dumpty situation and "something must be
 done". Hence Go stops with the undefined words and gives definite global
 meanings to type names. It would be helpful if D eschewed the C/C++
 heritage as well and got more definite about type names.
There is nothing Humpty Dumpty about the current situation. You are simply missing the fact that float and double are already defined as 32 bit/64 bit IEEE 754 compliant floating point numbers in the spec. There is nothing ambiguous about that, just as char/int/long have defined bit-widths in D.
Exactly. C/C++ has implementation-defined types, but D types are nailed down.
Jun 29 2014
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 2014-06-29 at 19:02 +0000, David Nadlinger via Digitalmars-d
wrote:
[=E2=80=A6]
 There is nothing Humpty Dumpty about the current situation. You=20
 are simply missing the fact that float and double are already=20
 defined as 32 bit/64 bit IEEE 754 compliant floating point=20
 numbers in the spec.
=20
 There is nothing ambiguous about that, just as char/int/long have=20
 defined bit-widths in D.
I think I am probably just getting "bloody minded" here, but=E2=80=A6 If D is a language that uses the underlying hardware representation then it cannot define the use of specific formats for hardware numbers. Thus, on hardware that provides IEEE754 format hardware float and double can map to the 32-bit and 64-bit IEEE754 numbers offered. However if the hardware does not provide IEEE754 hardware then either D must interpret floating point expressions (as per Java) or it cannot be ported to that architecture. cf. IBM 360. Fortunately more recent IBM hardware has multiple FPUs per core, one of which provides IEEE754 as an option. (Pity the other FPUs cannot be used :-) Corollary: if D defines the "hardware" representation in its data model then it can only be ported to hardware that uses that representation. PS Walter just wrote that the type real is not defined as float and double are, so it does have a Humpty Dumpty factor even if float and double do not. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 29 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 2:30 PM, Russel Winder via Digitalmars-d wrote:
 If D is a language that uses the underlying hardware representation then
 it cannot define the use of specific formats for hardware numbers. Thus,
 on hardware that provides IEEE754 format hardware float and double can
 map to the 32-bit and 64-bit IEEE754 numbers offered. However if the
 hardware does not provide IEEE754 hardware then either D must interpret
 floating point expressions (as per Java) or it cannot be ported to that
 architecture. cf. IBM 360.
That's correct. The D spec says IEEE 754.
 PS Walter just wrote that the type real is not defined as float and
 double are, so it does have a Humpty Dumpty factor even if float and
 double do not.
It's still IEEE, just the longer lengths if they exist on the hardware. D is not unique in requiring IEEE 754 floats - Java does, too. So does Javascript.
Jun 29 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 3:33 AM, Russel Winder via Digitalmars-d wrote:
 By being focused on Intel chips, D has failed to get floating point
 correct in avery analogous way to C failing to get floating point types
 right by focusing on PDP.
Sorry, I do not follow the reasoning here.
 Yes using 80-bit on Intel is good, but no-one
 else has this. Floating point sizes should be 32-, 64-, 128-, 256-bit,
 etc. D needs to be able to handle this. So does C, C++, Java, etc. Go
 will be able to handle it when it is ported to appropriate hardware as
 they use float32, float64, etc. as their types. None of this float,
 double, long double, double double rubbish.

 So D should perhaps make a breaking change and have types int32, int64,
 float32, float64, float80, and get away from the vagaries of bizarre
 type relationships with hardware?
D's spec says that the 'real' type is the max size supported by the FP hardware. How is this wrong?
Jun 28 2014
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 06/29/2014 02:40 AM, Walter Bright wrote:
 On 6/28/2014 3:33 AM, Russel Winder via Digitalmars-d wrote:
 ...
 So D should perhaps make a breaking change and have types int32, int64,
 float32, float64, float80, and get away from the vagaries of bizarre
 type relationships with hardware?
D's spec says that the 'real' type is the max size supported by the FP hardware. How is this wrong?
It is hardware-dependent.
Jun 28 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 6:14 PM, Timon Gehr wrote:
 On 06/29/2014 02:40 AM, Walter Bright wrote:
 On 6/28/2014 3:33 AM, Russel Winder via Digitalmars-d wrote:
 ...
 So D should perhaps make a breaking change and have types int32, int64,
 float32, float64, float80, and get away from the vagaries of bizarre
 type relationships with hardware?
D's spec says that the 'real' type is the max size supported by the FP hardware. How is this wrong?
It is hardware-dependent.
D does not require real to be 80 bits if the hardware does not support it. Keep in mind that D is a systems programming language, and that implies you get access to the hardware types.
Jun 28 2014
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 2014-06-28 at 17:40 -0700, Walter Bright via Digitalmars-d
wrote:
 On 6/28/2014 3:33 AM, Russel Winder via Digitalmars-d wrote:
 By being focused on Intel chips, D has failed to get floating point
 correct in avery analogous way to C failing to get floating point types
 right by focusing on PDP.
Sorry, I do not follow the reasoning here.
By being focused on specific hardware, you create names for types that do not port to other hardware. C and C++ really do not work well on IBM hardware because the PDP heritage of the type names does not port from PDP to IBM hardware.
 Yes using 80-bit on Intel is good, but no-one
 else has this. Floating point sizes should be 32-, 64-, 128-, 256-bit,
 etc. D needs to be able to handle this. So does C, C++, Java, etc. Go
 will be able to handle it when it is ported to appropriate hardware as
 they use float32, float64, etc. as their types. None of this float,
 double, long double, double double rubbish.

 So D should perhaps make a breaking change and have types int32, int64,
 float32, float64, float80, and get away from the vagaries of bizarre
 type relationships with hardware?
D's spec says that the 'real' type is the max size supported by the FP hardware. How is this wrong?
accurate the floating point number is until you ask and answer the question "and which processor are you running this code on". In many ways this is a trivial issue given C and C++ heritage, on the other hand Go and other languages are changing the game such that C and C++ thinking is being left behind. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 29 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 11:21 AM, Russel Winder via Digitalmars-d wrote:

 accurate the floating point number is until you ask and answer the
 question "and which processor are you running this code on".
That is not true with D. D specifies that float and double are IEEE 754 types which have specified size and behavior. D's real type is the largest the underlying hardware will support. D also specifies 'int' is 32 bits, 'long' is 64, and 'byte' is 8, 'short' is 16.
Jun 29 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 29 June 2014 at 19:22:16 UTC, Walter Bright wrote:
 On 6/29/2014 11:21 AM, Russel Winder via Digitalmars-d wrote:

 how
 accurate the floating point number is until you ask and answer 
 the
 question "and which processor are you running this code on".
That is not true with D. D specifies that float and double are IEEE 754 types which have specified size and behavior. D's real type is the largest the underlying hardware will support. D also specifies 'int' is 32 bits, 'long' is 64, and 'byte' is 8, 'short' is 16.
I'm afraid that it is exactly true if you use `real`. What important use-case is there for using `real` that shouldn't also be accompanied by a `static assert(real.sizeof >= 10);` or similar, for correctness reasons? Assuming there isn't one, then what is the point of having a type with hardware dependant precision? Isn't it just a useless abstraction over the hardware that obscures useful intent? mixin(`alias real` ~ (real.sizeof*8).stringof ~ ` = real;`); is more useful to me.
Jun 29 2014
next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 29 June 2014 22:04, John Colvin via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Sunday, 29 June 2014 at 19:22:16 UTC, Walter Bright wrote:
 On 6/29/2014 11:21 AM, Russel Winder via Digitalmars-d wrote:

 accurate the floating point number is until you ask and answer the
 question "and which processor are you running this code on".
That is not true with D. D specifies that float and double are IEEE 754 types which have specified size and behavior. D's real type is the largest the underlying hardware will support. D also specifies 'int' is 32 bits, 'long' is 64, and 'byte' is 8, 'short' is 16.
I'm afraid that it is exactly true if you use `real`.
There seems to be a circular argument going round here, it's tiring bringing up the same point over and over again.
 What important use-case is there for using `real` that shouldn't also be
 accompanied by a `static assert(real.sizeof >= 10);` or similar, for
 correctness reasons?
Breaks portability. There is just too much code out there that uses real, and besides druntime/phobos math has already been ported to handle all cases where real == 64bits.
 Assuming there isn't one, then what is the point of having a type with
 hardware dependant precision? Isn't it just a useless abstraction over the
 hardware that obscures useful intent?

 mixin(`alias real` ~ (real.sizeof*8).stringof ~ ` = real;`);
Good luck guessing which one to use. On GDC you have a choice of three or four depending on what the default -m flags are. ;)
Jun 29 2014
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 2:04 PM, John Colvin wrote:
 Assuming there isn't one, then what is the point of having a type with hardware
 dependant precision?
The point is D is a systems programming language, and the D programmer should not be locked out of the hardware capabilities of the system he is running on. D should not be constrained to be the least common denominator of all and future processors.
Jun 29 2014
prev sibling parent reply Element 126 <dlang.element126 gmail.com> writes:
On 06/29/2014 11:04 PM, John Colvin wrote:
 [...]

 mixin(`alias real` ~ (real.sizeof*8).stringof ~ ` = real;`);

 is more useful to me.
Be careful : this code is tricky ! real.sizeof is the storage size, ie 16 bytes on x86_64. The following happily compiles ;-) import std.conv: to; mixin(`alias real` ~ to!string(real.sizeof*8) ~ ` = real;`); static assert(real128.mant_dig == 64); void main() { real128 x = 1.0; }
Jun 30 2014
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 30 June 2014 at 16:29:06 UTC, Element 126 wrote:
 On 06/29/2014 11:04 PM, John Colvin wrote:
 [...]

 mixin(`alias real` ~ (real.sizeof*8).stringof ~ ` = real;`);

 is more useful to me.
Be careful : this code is tricky ! real.sizeof is the storage size, ie 16 bytes on x86_64. The following happily compiles ;-) import std.conv: to; mixin(`alias real` ~ to!string(real.sizeof*8) ~ ` = real;`); static assert(real128.mant_dig == 64); void main() { real128 x = 1.0; }
I knew there'd be something tricky in there. Thanks for spotting it.
Jun 30 2014
prev sibling next sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
Hopefully there are points here for pedantry and bloody mindedness=E2=80=A6


On Sat, 2014-06-28 at 18:32 -0700, Walter Bright via Digitalmars-d
wrote:
[=E2=80=A6]
 Keep in mind that D is a systems programming language, and that
implies you get=20
 access to the hardware types.
On Sun, 2014-06-29 at 12:22 -0700, Walter Bright via Digitalmars-d wrote: [=E2=80=A6].
=20
 That is not  true with D. D specifies that float and double are IEEE 754 =
types=20
 which have specified size and behavior. D's real type is the largest the=
=20
 underlying hardware will support.
=20
 D also specifies 'int' is 32 bits, 'long' is 64, and 'byte' is 8, 'short'=
is 16. D gives access to the hardware types, and D defines the structure of all those types. The only resolution is that D only works on that hardware where the hardware types are the ones D defines. Thus D only works on a subset of hardware, and can never be ported to hardware where the hardware types differ from those defined by D. So D float and double will not work on IBM 360 unless interpreted, and real would be 128-bit (not IEEE)? The D real type definitely suffers the C/C++ float and double problem! I guess we just hope that all future hardware is IEEE754 compliant. (This is both a trivial issue and a brick wall issue so let's keep thing humour-ful!) --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 29 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 2:45 PM, Russel Winder via Digitalmars-d wrote:
 So D float and double will not work on IBM 360 unless interpreted,
That's right. On the other hand, someone could create a "D360" fork of the language that was specifically targetted to the 360. Nothing wrong with that. Why burden the other 99.999999% of D programmers with 360 nutburger problems?
 I guess we just hope that all future hardware is IEEE754 compliant.
I'm not concerned about it. No CPU maker in their right head would do something different. I've witnessed decades of "portable" C code where the programmer tried to be "portable" in his use of int's and char's, but never tested it on a machine where those sizes are different, and when finally it was tested it turned out to be broken. Meaning that whether the D spec defines 360 portability or not, there's just no way that FP code is going to be portable to the 360 unless someone actually tests it. 1's complement, 10 bit bytes, 18 bit words, non-IEEE fp, are all DEAD. I can pretty much guarantee you that about zero of C/C++ programs will actually work without modification on those systems, despite the claims of the C/C++ Standard. I'd also bet you that most C/C++ code will break if ints are 64 bits, and about 99% will break if you try to compile them with a 16 bit C/C++ compiler. 90% will break if you feed it EBCDIC.
Jun 29 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Sunday, 29 June 2014 at 22:49:44 UTC, Walter Bright wrote:
 I guess we just hope that all future hardware is IEEE754 
 compliant.
I'm not concerned about it. No CPU maker in their right head would do something different.
AFAIK they break compliance all the time.
Jun 30 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 4:25 AM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On Sunday, 29 June 2014 at 22:49:44 UTC, Walter Bright wrote:
 I guess we just hope that all future hardware is IEEE754 compliant.
I'm not concerned about it. No CPU maker in their right head would do something different.
AFAIK they break compliance all the time.
Examples, please.
Jun 30 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 30 June 2014 at 16:54:55 UTC, Walter Bright wrote:
 On 6/30/2014 4:25 AM, "Ola Fosheim Grøstad" 
 <ola.fosheim.grostad+dlang gmail.com>" wrote:
 AFAIK they break compliance all the time.
Examples, please.
Cell: http://publib.boulder.ibm.com/infocenter/cellcomp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.cell.doc/proguide/spu_sp_diffs.html Intel: http://www.velocityreviews.com/threads/intel-fp-h-w-non-compliance-to-ieee754.746517/ ARM Neon vs VPF… etc.
Jun 30 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 3:14 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On Monday, 30 June 2014 at 16:54:55 UTC, Walter Bright wrote:
 On 6/30/2014 4:25 AM, "Ola Fosheim Grøstad"
 <ola.fosheim.grostad+dlang gmail.com>" wrote:
 AFAIK they break compliance all the time.
Examples, please.
Cell: http://publib.boulder.ibm.com/infocenter/cellcomp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.cell.doc/proguide/spu_sp_diffs.html
Wow. Fortunately, there's a switch http://publib.boulder.ibm.com/infocenter/cellcomp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.cell.doc/progui e/spu_sp_diffs.html so it'll work correctly.
 Intel:

 http://www.velocityreviews.com/threads/intel-fp-h-w-non-compliance-to-ieee754.746517/
That one looks like a bug.
Jun 30 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Monday, 30 June 2014 at 22:58:48 UTC, Walter Bright wrote:
 Wow. Fortunately, there's a switch 
 http://publib.boulder.ibm.com/infocenter/cellcomp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.cell.doc/progui
e/spu_sp_diffs.html 
 so it'll work correctly.
That's the same link I provided, but I presume the compiler switch kills performance? You have the same with ARM processors. NEON (SIMD) instructions are not IEEE754 compliant. VPF is almost compliant, but does not support subnormal numbers and flush them to zero. Which can be a disaster… So basically, floating point is not portable unless you give up performance or check all expressions with worst case analysis based on deficiencies on all current platforms.
Jun 30 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 11:58 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On Monday, 30 June 2014 at 22:58:48 UTC, Walter Bright wrote:
 Wow. Fortunately, there's a switch
 http://publib.boulder.ibm.com/infocenter/cellcomp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.cell.doc/proguide/spu_sp_diffs.html
 so it'll work correctly.
That's the same link I provided, but I presume the compiler switch kills performance?
Click on "compiling for strict IEEE conformance"
 You have the same with ARM processors. NEON (SIMD) instructions are
 not IEEE754 compliant. VPF is almost compliant, but does not support subnormal
 numbers and flush them to zero. Which can be a disaster…
It wouldn't be any different if the D spec says "floating point is, ya know, whatevah". You can't fix stuff like this in the spec.
 So basically, floating point is not portable unless you give up performance or
 check all expressions with worst case analysis based on deficiencies on all
 current platforms.
As I've posted before, nobody's FP code is going to work on such platforms out of the box even if the spec is accommodating for it. The whole point of IEEE 754 is to make portable FP code possible. Besides, Java and Javascript, for example, both require IEEE conformance.
Jul 01 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Tuesday, 1 July 2014 at 16:58:55 UTC, Walter Bright wrote:
 Click on "compiling for strict IEEE conformance"
It also states that compliance affect performance.
 not IEEE754 compliant. VPF is almost compliant, but does not 
 support subnormal
 numbers and flush them to zero. Which can be a disaster…
It wouldn't be any different if the D spec says "floating point is, ya know, whatevah". You can't fix stuff like this in the spec.
Well, the difference is that you can make VPF mostly compliant, but that means you trap subnormal numbers and fix it in software. Which affects performance. If the specs require IEEE754 compliance then you default to software emulation and have to turn it off through compiler switches. Here is another example: the parallella Coprocessor from Adapteva: «The CPU is compatible with the IEEE-754 single-precision format, with the following exceptions: - No support for inexact flags. - NAN inputs generate an invalid exception and return a quiet NAN. When one or both of the inputs are NANs, the sign bit of the operation is set as an XOR of the signs of the input sign bits. - Denormal operands are flushed to zero when input to a computation unit and do not generate an underflow exception. Any denormal or underflow result from an arithmetic operation is flushed to zero and an underflow exception is generated. - Round-to-±infinity is not supported.»
 Besides, Java and Javascript, for example, both require IEEE 
 conformance.
But they aren't system level programming languages… and we probably cannot expect future many-core processors or transputer-like processors to waste die space in order to conform. So sure you can specify the IEEE-754 spec and just make D run at full rate on typical CISC CPUs, but the alternative is to constrain the promise of compliance to what is typical for efficient CPUs. Then have a "-strict" flag for the few applications that are scientific in nature. That would be more in line with system level programming.
Jul 01 2014
next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 1 July 2014 20:36, via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Tuesday, 1 July 2014 at 16:58:55 UTC, Walter Bright wrote:
 Click on "compiling for strict IEEE conformance"
It also states that compliance affect performance.
 not IEEE754 compliant. VPF is almost compliant, but does not support
 subnormal
 numbers and flush them to zero. Which can be a disaster…
It wouldn't be any different if the D spec says "floating point is, ya know, whatevah". You can't fix stuff like this in the spec.
Well, the difference is that you can make VPF mostly compliant, but that means you trap subnormal numbers and fix it in software. Which affects performance. If the specs require IEEE754 compliance then you default to software emulation and have to turn it off through compiler switches. Here is another example: the parallella Coprocessor from Adapteva: «The CPU is compatible with the IEEE-754 single-precision format, with the following exceptions: - No support for inexact flags. - NAN inputs generate an invalid exception and return a quiet NAN. When one or both of the inputs are NANs, the sign bit of the operation is set as an XOR of the signs of the input sign bits. - Denormal operands are flushed to zero when input to a computation unit and do not generate an underflow exception. Any denormal or underflow result from an arithmetic operation is flushed to zero and an underflow exception is generated. - Round-to-±infinity is not supported.»
The crucial thing here is that the layout of float/double types are IEEE 754 are compatible. :) These behaviours you describe only affect the FP control functions in std.math, which are the only thing platform specific, and can only be written in inline assembly anyway... Regards Iain
Jul 02 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 2 July 2014 at 08:52:25 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 The crucial thing here is that the layout of float/double types 
 are
 IEEE 754 are compatible. :)
That's nice of course, if you import/export, but hardly the only crucial thing. Implied correctness and warnings when assumptions break is also important…
 These behaviours you describe only affect the FP control 
 functions in
 std.math, which are the only thing platform specific, and can 
 only be
 written in inline assembly anyway...
It affects the backend. It affects vectorization. (NEON is not IEEE754 AFAIK) It affects what a conforming D compiler is allowed to do. It affects versioning. E.g. you can have a flags IEEE754_STRICT or IEE754_HAS_NAN etc and use versioning that dectects the wrong compiler-mode.
Jul 02 2014
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 2 July 2014 12:42, via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Wednesday, 2 July 2014 at 08:52:25 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 The crucial thing here is that the layout of float/double types are
 IEEE 754 are compatible. :)
That's nice of course, if you import/export, but hardly the only crucial thing. Implied correctness and warnings when assumptions break is also important…
 These behaviours you describe only affect the FP control functions in
 std.math, which are the only thing platform specific, and can only be
 written in inline assembly anyway...
It affects the backend.
Only matters if you have to implement it in your backend
 It affects vectorization. (NEON is not IEEE754 AFAIK)
Vectors are treated differently from floats
 It affects what a conforming D compiler is allowed to do.
That depends what you mean be 'conforming'.
 It affects versioning.

 E.g. you can have a flags IEEE754_STRICT or IEE754_HAS_NAN etc and use
 versioning that dectects the wrong compiler-mode.
Affects only library maintainers, but I haven't looked too much into what gcc offers as a platform regarding this. The ARM market is terrible, and it will certainly be the case that we *can't* have a one size fits all solution. But in the standard libraries we can certainly keep strictly in line with the most conforming chips, so if you wish to support X you may do so in a platform-specific fork. This is certainly not unusual for druntime (eg: minilibd) Regards Iain
Jul 02 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 2 July 2014 at 16:03:47 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 Only matters if you have to implement it in your backend
You have to implement it in the backend if D requires strict IEEE754 conformance?
 Vectors are treated differently from floats
How can you then let the compiler vectorize? You can't. Meaning, your code will run very slow.
 It affects versioning.

 E.g. you can have a flags IEEE754_STRICT or IEE754_HAS_NAN etc 
 and use
 versioning that dectects the wrong compiler-mode.
Affects only library maintainers, but I haven't looked too much into what gcc offers as a platform regarding this.
I don't agree. If your code produce denormal numbers then it matters a lot if they are forced to zero or not. Just think about divison by zero traps. Why would this only be a library issue? If you write portable code you shouldn't have to second guess what the compiler does. It either guarantees that denormal numbers are not flushed to zero, or it does not. If it does not then D does not require IEEE754 and you will have to think about this when you write your code.
 The ARM market is terrible, and it will certainly be the case 
 that we
 *can't* have a one size fits all solution.  But in the standard
 libraries we can certainly keep strictly in line with the most
 conforming chips, so if you wish to support X you may do so in a
 platform-specific fork.
I don't really understand the reasoning here. Is D Intel x86 specific? Meaning, it is a system level programming language on x86 only and something arbitrary on other platforms? Either D requires IEEE754 strict mode, or it does not. It matters what the default is.
Jul 02 2014
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 2 July 2014 19:58, via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Wednesday, 2 July 2014 at 16:03:47 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 Only matters if you have to implement it in your backend
You have to implement it in the backend if D requires strict IEEE754 conformance?
No, you don't. At least I just let the gcc backend take care of whatever behaviours occur. Which tend to be based around C as a baseline.
 Vectors are treated differently from floats
How can you then let the compiler vectorize? You can't. Meaning, your code will run very slow.
Easily - it does this for you so long as it determines that it is beneficial.
 The ARM market is terrible, and it will certainly be the case that we
 *can't* have a one size fits all solution.  But in the standard
 libraries we can certainly keep strictly in line with the most
 conforming chips, so if you wish to support X you may do so in a
 platform-specific fork.
I don't really understand the reasoning here. Is D Intel x86 specific?
Yes it is, more than you might realise. I've been spending the last 4 years breaking it to be platform agnostic. :o) Regards Iain
Jul 02 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 2:28 PM, Iain Buclaw via Digitalmars-d wrote:
 On 2 July 2014 19:58, via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 I don't really understand the reasoning here. Is D Intel x86 specific?
Yes it is, more than you might realise. I've been spending the last 4 years breaking it to be platform agnostic. :o)
I think you're conflating dmd with D. And IEEE 754 is a standard.
Jul 02 2014
next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3 Jul 2014 01:50, "Walter Bright via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 On 7/2/2014 2:28 PM, Iain Buclaw via Digitalmars-d wrote:
 On 2 July 2014 19:58, via Digitalmars-d <digitalmars-d puremagic.com>
wrote:
 I don't really understand the reasoning here. Is D Intel x86 specific?
Yes it is, more than you might realise. I've been spending the last 4 years breaking it to be platform agnostic. :o)
I think you're conflating dmd with D.
I suppose I am just a bit. At the time I was thinking about the spec on _argptr (which has been fixed), __simd and intrinsics.
Jul 02 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 11:38 PM, Iain Buclaw via Digitalmars-d wrote:
 I suppose I am just a bit. At the time I was thinking about the spec on _argptr
 (which has been fixed), __simd and intrinsics.
You do have a good point with those aspects.
Jul 02 2014
prev sibling parent "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Thursday, 3 July 2014 at 00:49:33 UTC, Walter Bright wrote:
 On 7/2/2014 2:28 PM, Iain Buclaw via Digitalmars-d wrote:
 On 2 July 2014 19:58, via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
 I don't really understand the reasoning here. Is D Intel x86 
 specific?
Yes it is, more than you might realise. I've been spending the last 4 years breaking it to be platform agnostic. :o)
I think you're conflating dmd with D. And IEEE 754 is a standard.
I understand what you're saying here, which is that any conflation of D with x86 is a fault in the implementation rather than the spec, but at the end of the day, D lives by its implementation. It's not just about what the dmd backend supports per se, but about what assumptions that leads people to make when writing code for the frontend, runtime and standard library. Iain has done some heroic work in the last year going through compiler frontend, runtime and Phobos and correcting code with faulty assumptions such as "real == 80 bit floating point" (which IIRC was often made as a general assumption even though it's x86-specific).
Jul 03 2014
prev sibling parent reply "Wanderer" <no-reply no-reply.org> writes:
On Tuesday, 1 July 2014 at 19:36:26 UTC, Ola Fosheim Grøstad 
wrote:
 Besides, Java and Javascript, for example, both require IEEE 
 conformance.
But they aren't system level programming languages… and we probably cannot expect future many-core processors or transputer-like processors to waste die space in order to conform.
So it's okay for "system level programming languages" to produce numeric garbage when it comes to floating points? ;-) Sorry, couldn't resist. Some people keep claiming that D is a "system level programming language" despite there is no single OS and no single hardware driver written in D yet. Which sorta puts D and Java into the same boat. Besides - gasp! - Java *is* a system level programming language after all. There are platforms/devices which support Java bytecode natively. For system programming, it's extra important that the same algorithm produces exactly the same results on different environments. And the speed is not always the most important factor.
Jul 02 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 2 July 2014 at 12:16:18 UTC, Wanderer wrote:
 So it's okay for "system level programming languages" to 
 produce numeric garbage when it comes to floating points? ;-)
System level programming languages provide direct easy access to the underlying hardware foundation.
 Sorry, couldn't resist. Some people keep claiming that D is a 
 "system level programming language" despite there is no single 
 OS and no single hardware driver written in D yet.
D is not even production ready, so why should there be? Who in their right mind would use a language in limbo for building a serious operating system or do embedded work? You need language stability and compiler maturity first.
Jul 02 2014
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 5:24 AM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 D is not even production ready,
Of course it is.
Jul 02 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 2 July 2014 at 21:45:41 UTC, Walter Bright wrote:
 On 7/2/2014 5:24 AM, "Ola Fosheim Grøstad" 
 <ola.fosheim.grostad+dlang gmail.com>" wrote:
 D is not even production ready,
Of course it is.
Not by my definition of "production ready": 1. Not stable or up to date language spec. 2. Outstanding significant issues in the bug tracker. 3. No mature compiler. 4. No mature runtime. 5. No stable std library. 6. No entity/vendor that provides support/maintenance for a specific version of D for a specified period of time. Would you use D for building software to ship with hardware appliances? I would not.
Jul 03 2014
next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3 July 2014 22:43, via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Wednesday, 2 July 2014 at 21:45:41 UTC, Walter Bright wrote:
 On 7/2/2014 5:24 AM, "Ola Fosheim Grøstad"
 <ola.fosheim.grostad+dlang gmail.com>" wrote:
 D is not even production ready,
Of course it is.
Not by my definition of "production ready": 1. Not stable or up to date language spec. 2. Outstanding significant issues in the bug tracker. 3. No mature compiler. 4. No mature runtime. 5. No stable std library. 6. No entity/vendor that provides support/maintenance for a specific version of D for a specified period of time.
You must know something I don't. :o)
Jul 03 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Thu, Jul 03, 2014 at 09:43:38PM +0000, via Digitalmars-d wrote:
 On Wednesday, 2 July 2014 at 21:45:41 UTC, Walter Bright wrote:
On 7/2/2014 5:24 AM, "Ola Fosheim Grøstad"
<ola.fosheim.grostad+dlang gmail.com>" wrote:
D is not even production ready,
Of course it is.
Not by my definition of "production ready":
[...]
 2. Outstanding significant issues in the bug tracker.
[...] I find this particular statement rather amusing. At my day job I work with "enterprise" software, which is currently running on dedicated hardware sold to major corporate customers worldwide. To say that the state of the bug tracker barely even begins to approach the state of D's bugtracker, would be the understatement of the century. We have so many outstanding bugs, ranging from minor to subtle-but-nasty to major design problems, that the PTBs have given up on trying to rein in the bug count, and have resorted to measures like closing bugs due to inactivity. The number of "outstanding significant issues" that get postponed past releases due to lack of resources, is enough to send chills down one's back, if he has any sense of pride in his work at all. Yet this bug-ridden software was deemed "production ready" (whatever that means), and is in fact running in mission-critical services on customer sites. By comparison, the state of D's bug tracker looks a lot more promising. T -- Political correctness: socially-sanctioned hypocrisy.
Jul 03 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/3/2014 2:43 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 Would you use D for building software to ship with hardware appliances?
Yes.
 I would not.
The issues you presented are subjective and a matter of opinion. Regardless of the state of D, I'm not the type who wilts at an issue or two - I work around it. And so does everyone else who does production work. If you sit around waiting for arbitrary perfection, you'll never get any work done. I don't care that my truck has dings in it, either, it's a truck and it's useful for what I need it for :-)
Jul 03 2014
next sibling parent "Paolo Invernizzi" <paolo.invernizzi no.address> writes:
On Friday, 4 July 2014 at 01:26:37 UTC, Walter Bright wrote:
 
 The issues you presented are subjective and a matter of 
 opinion. Regardless of the state of D, I'm not the type who 
 wilts at an issue or two - I work around it. And so does 
 everyone else who does production work.

 If you sit around waiting for arbitrary perfection, you'll 
 never get any work done. I don't care that my truck has dings 
 in it, either, it's a truck and it's useful for what I need it 
 for :-)
Well said, and that's exactly how things tend to works. --- Paolo
Jul 04 2014
prev sibling next sibling parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Friday, 4 July 2014 at 01:26:37 UTC, Walter Bright wrote:

 If you sit around waiting for arbitrary perfection, you'll 
 never get any work done. I don't care that my truck has dings 
 in it, either, it's a truck and it's useful for what I need it 
 for :-)
Even though a Tesla is of no more use than your old ugly truck, I still favor the former. :P
Jul 04 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 1:37 AM, Max Samukha wrote:
 On Friday, 4 July 2014 at 01:26:37 UTC, Walter Bright wrote:

 If you sit around waiting for arbitrary perfection, you'll never get any work
 done. I don't care that my truck has dings in it, either, it's a truck and
 it's useful for what I need it for :-)
Even though a Tesla is of no more use than your old ugly truck, I still favor the former. :P
You wouldn't use a Tesla for hauling!
Jul 04 2014
prev sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Friday, 4 July 2014 at 01:26:37 UTC, Walter Bright wrote:
 The issues you presented are subjective and a matter of opinion.
Well, one has to agree on a definition for a start! :)
 If you sit around waiting for arbitrary perfection, you'll 
 never get any work done.
I pick the most stable tool for the job. Meaning I usually end up with C, conservative use of C++, Python 2.7, Javascript, SQL or XSLT… :-P Rarely D and occasionally Dart (which isn't particularly stable either and is rejected beacuase of it) and Php (which is pretty stable). It's a matter of priority. If the D maintainers don't care about reaching a stable state, at the expense of scope and features, then it will never be the best tool for the job. I regret that.
Jul 04 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ola Fosheim Grøstad:

 If the D maintainers don't care about reaching a stable state, 
 at the expense of scope and features,
Don't be silly, D devs care a lot about reaching stability, fixing bugs, etc. Bye, bearophile
Jul 04 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Friday, 4 July 2014 at 12:59:41 UTC, bearophile wrote:
 If the D maintainers don't care about reaching a stable state, 
 at the expense of scope and features,
Don't be silly, D devs care a lot about reaching stability, fixing bugs, etc.
But not to the extent that they are willing to limit the scope and features to get there in reasonable time for D2 (say 10 months), so the feature set is expanding and the scope of the standard library is too big for a stable mature library that is easy to use to be feasible as far as I can tell. Dart is going down the same path. It affects adoption, which in turn affects the eco system. Basically Dart pushed their commercial adoption two years into the future by not commiting to stable platform support, claming that they only support "evergreen browsers", whatever that means. Which pretty much lets Google, Apple and Microsoft define platform stability. I'm not trying to be pushy or silly. I just want to know if the most probable path for an alternative system development language is a fork or spinning up a new project. Evolutionary development is great when there is great uncertainty and you need prototyping, but then you need to focus on getting to something that is tight, uniform, portable (future proof) and feasible with the available resources. A good starting point would be to get down to locking down the specs in a coherent and platform agnostic manner, then plan for making a mature toolset to support it. The D spec should be clear on what IEEE 754 compliance actually means and relate it to all probable scenarios. That would be a very useful exercise in decision making.
Jul 04 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 12:07 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 The D spec should be clear on what IEEE 754 compliance actually
 means and relate it to all probable scenarios.
I'm curious how that would affect anyone currently using dmd/gdc/ldc in getting professional work done.
Jul 04 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Friday, 4 July 2014 at 19:53:11 UTC, Walter Bright wrote:
 I'm curious how that would affect anyone currently using 
 dmd/gdc/ldc in getting professional work done.
It doesn't affect them since they are on x86 (until they want to use co-processor auto-vectorization). As far as I can tell, also Intel CPUs such as Phi are faster if you skip on IEEE754 conformance for denormal numbers. So I think this is a trend, backed empirically by CPUs by IBM, ARM and Intel. The most important factor is that it does affect the credibility of the spec. The spec is the vision that people either embrace or reject. For those devs who aren't happy with status quo having a credible spec that the team is committed to is important, because it says what outcome they can expect if they start contributing. There is very little incentive to contribute if you think that the current D incarnation is insufficient, unless the team specs out what D is to become. If you can commit to a spec for D2 that is final, then you can also plan for when D2 is done.
Jul 04 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 1:13 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 If you can commit to a spec for D2 that is final, then you can also plan for
 when D2 is done.
There's no such thing as done for a working language. C++, for example, is constantly in flux. Every release by every vendor alters which parts of the standard and draft standard it supports. Furthermore, the C/C++ Standards don't have much to say about how floating point works - how is that of any help in writing professional, stable fp code? Do we want to make the spec better? Yes. Does that impair professional use of D now? No. Do we accept pull requests on the spec to make it better? Yes. Have you contributed to any pull requests to improve the spec? Please, contribute to the things you care about, instead of suggesting in the n.g. that others should do it. That would be far more helpful.
Jul 04 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Friday, 4 July 2014 at 20:28:36 UTC, Walter Bright wrote:
 There's no such thing as done for a working language. C++, for 
 example, is constantly in flux. Every release by every vendor 
 alters which parts of the standard and draft standard it 
 supports.
And no sane devs rely on those experimental parts unless g++ or clang commits themselves to them. The C++ standard specs out things in advance at intervals specified in years, not weeks.
 Furthermore, the C/C++ Standards don't have much to say about 
 how floating point works - how is that of any help in writing 
 professional, stable fp code?
You know that you are on your own and cannot make assumptions about conformance, and address it with code (like ifdefs).
 Do we want to make the spec better? Yes.
Not make the spec better or bring it up to date with the implementation. Spec out the language so people know what the missing bits are.
 Please, contribute to the things you care about, instead of 
 suggesting in the n.g. that others should do it. That would be 
 far more helpful.
That would imply a fork. And yes, I think that might be the most likely outcome that someone forks it. I don't believe in language design by a comittee. I think the language designers should spec out their vision. Let the community point out the flaws. Go back to the drawing board. Do some rounds. Then commit to it. I think that would attract more contribution to the core language development. I am interested in contributing code to make a good spec come to life, not to add noise to an endless contractual metamorphosis that never will lead to anything consistent and coherent.
Jul 04 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 1:41 PM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 On Friday, 4 July 2014 at 20:28:36 UTC, Walter Bright wrote:
 There's no such thing as done for a working language. C++, for example, is
 constantly in flux. Every release by every vendor alters which parts of the
 standard and draft standard it supports.
And no sane devs rely on those experimental parts unless g++ or clang commits themselves to them. The C++ standard specs out things in advance at intervals specified in years, not weeks.
As I said, C++ vendors often implement things far in advance of spec approval, they do it piecemeal, and different vendors do things in different orders. C++ evangelists are constantly rewriting what C++ "best practices" are. To characterize all this churn as "stablility" is awfully charitable.
 Furthermore, the C/C++ Standards don't have much to say about how floating
 point works - how is that of any help in writing professional, stable fp code?
You know that you are on your own and cannot make assumptions about conformance, and address it with code (like ifdefs).
Uh-huh. And how much professional code have you seen that had #ifdef's for Vax fp in it? IBM fp? Future CPUs that don't exist yet? How many developers have access to a Vax to test their #ifdef's on? Next, consider how much C++ code breaks when ported from 32 to 64 bits. It's most of it, even mine, and I know what I'm doing. What you're implying is saying that when a spec says "implementation defined" then voila! the code is portable!
 Do we want to make the spec better? Yes.
Not make the spec better or bring it up to date with the implementation. Spec out the language so people know what the missing bits are.
Please contribute to those areas of the spec you feel need improvement. Non-specific statements like "bring it up to date" are not helpful.
 Please, contribute to the things you care about, instead of suggesting in the
 n.g. that others should do it. That would be far more helpful.
That would imply a fork. And yes, I think that might be the most likely outcome that someone forks it.
A pull request does not imply a fork.
 I don't believe in language design by a comittee.
The only alternative is you believe I need to do all the work. This is not possible. I am not superman, nor am I expert at everything. Sadly, this also implies that there are no computer languages you believe in. You set an impossible standard. How can you possibly say you prefer C++, a classic design by committee language?
 I think the language designers
 should spec out their vision. Let the community point out the flaws. Go back to
 the drawing board. Do some rounds. Then commit to it.

 I think that would attract more contribution to the core language development.
I'm asking you to contribute. These posts do not accomplish anything. Exhorting me to do more (I already work on D 24/7) cannot work.
 I am interested in contributing code to make a good spec come to life, not to
 add noise to an endless contractual metamorphosis that never will lead to
 anything consistent and coherent.
Nothing will improve if you and others remain on the sidelines. Get out in front and make what you want to happen, happen.
Jul 04 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Friday, 4 July 2014 at 21:08:27 UTC, Walter Bright wrote:
 rewriting what C++ "best practices" are. To characterize all 
 this churn as "stablility" is awfully charitable.
Pfft, a lot of performance C++ code is roughly in 1998 land without exceptions and rtti.
 Uh-huh. And how much professional code have you seen that had 
 #ifdef's for Vax fp in it? IBM fp? Future CPUs that don't exist 
 yet? How many developers have access to a Vax to test their 
 #ifdef's on?
It is not uncommon for portable DSP code to have ifdefs. It is not uncommon to have ifdefs for extracting the mantissa etc. Heck, even for uints you might need ifdefs, to account for whether you have wrapping uints or not in phase counters. (wrapping over 31 bits or 32 bits) Considering that denormal numbers being flushed to zero is non-standard and not uncommon, it would be wise to somehow support it with version{}, so you can specify what assumptions a particular function make. That way you might get "not implemented" as a compile time error when porting to a new platform.
 What you're implying is saying that when a spec says 
 "implementation defined" then voila! the code is portable!
No, it says "voila! the code is not portable" and then you can inject your own guards that might prevent it from compiling on nonconforming platforms and let you know what you need to look at.
 Sadly, this also implies that there are no computer languages 
 you believe in. You set an impossible standard. How can you 
 possibly say you prefer C++, a classic design by committee 
 language?
I don't prefer it. I think it sucks, but it is the only viable choice if you want to create a scalable game or virtual world server. And since C++ is the crappy shit it is, you usually have to build a language on top of it to keep the server stable and modifiable and stay sane. A key benefit of a tighter version of D would be to avoid that extra layer IMO.
 I'm asking you to contribute. These posts do not accomplish 
 anything. Exhorting me to do more (I already work on D 24/7) 
 cannot work.
Maybe you and Andrei could consider having other people do the stuff you don't have to do, but that other people can take care of? Because I think you and Andrei are the only ones who can spec out the changes that would make D a clean delightful language to use and get acceptance for it in the community. The alternative is to fork it, cut down on features, clean up the syntax for DSL purposes, rip out the GC and add transactional memory support. I think the current process is too slow for outsiders to get D to production level in the domains where speed and stability truly matters.
Jul 04 2014
parent reply "Paolo Invernizzi" <paolo.invernizzi no.address> writes:
On Friday, 4 July 2014 at 21:49:33 UTC, Ola Fosheim Grøstad wrote:
 On Friday, 4 July 2014 at 21:08:27 UTC, Walter Bright wrote:

 Sadly, this also implies that there are no computer languages 
 you believe in. You set an impossible standard. How can you 
 possibly say you prefer C++, a classic design by committee 
 language?
I don't prefer it. I think it sucks, but it is the only viable choice if you want to create a scalable game or virtual world server.
Again, outside, in the real business world, reality is a little different: take this monster, look, no C++! http://www.robg3d.com/2014/01/why-ccp-is-still-using-python-2/ http://www.pcgamer.com/2013/06/15/eve-online/ What I loved about D, from the real beginning, was this: pragmatism, pragmatism! And after the love, what moved us as a company to adopt it was Walter: He is a deeply pragmatic guy! Pragmatism is an invaluable asset in business (btw, THAT should be stressed in the logo/identity/redesign looooooong thread) --- Paolo
Jul 05 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 5 July 2014 at 09:39:10 UTC, Paolo Invernizzi wrote:
 Again, outside, in the real business world, reality is a little
 different: take this monster, look, no C++!

 http://www.robg3d.com/2014/01/why-ccp-is-still-using-python-2/
 http://www.pcgamer.com/2013/06/15/eve-online/
I don't play Eve, but in general the challenge in virtual worlds is that you need to do full veracity checking on the server to reduce cheating. You should also hide parts of the model so that only the server knows it. Basically, you have to run the entire sim on the server and only run parts of it on the client for display purposes if you want to reduce cheating without introducing draconian measures that basically takes over the machine (which cannot work if the client runs in the browser). Anyway, at the end of the day, for a freemium game you need to cut server costs because you cannot estimate correctly how much money you make per online user. With a subscription model you are better off and can spend more on hardware. What you can or cannot do, depends on the business model, the market and the game design…
 What I loved about D, from the real beginning, was this:
 pragmatism, pragmatism!
I am pragmatic about this. I have stuff planned that can run on Python on top of Google Datastore on the server and use Dart+WebGL on the client. But if you want a physics based model, user building and fast travelling you have to consider the worst case scenario and you cannot do it in Python or using a disk based database. You need a in-memory database and hit the hardware so that you can take the peaks without ending up with molasses of latency.
 And after the love, what moved us as a company to adopt it was
 Walter: He is a deeply pragmatic guy!
 Pragmatism is an invaluable asset in business (btw, THAT should
 be stressed in the logo/identity/redesign looooooong thread)
The most valuable factor in business is predictability, opportunities and being better at cutting costs than the competition. Google are pragmatic, they dump IE9 on most of their platforms. Unfortunately for businesses using Google tech that means loss of predictability, lost opportunities and increased costs. Pragmatism in the context of D is community building. Sure, being pragmatic about the logo is important, you should encourage people using it in different ways because it is a community building tool (among many). Like the penguin in Linux being used in games etc. Community building means encouraging participation and setting direction. If you don't set direction, people will sit on the fence waiting for something to happen. Communities don't build skeletons, they add meat to the bones.
Jul 05 2014
parent reply "Paolo Invernizzi" <paolo.invernizzi no.address> writes:
On Saturday, 5 July 2014 at 11:14:40 UTC, Ola Fosheim Grøstad
wrote:
 On Saturday, 5 July 2014 at 09:39:10 UTC, Paolo Invernizzi 
 wrote:
 Again, outside, in the real business world, reality is a little
 different: take this monster, look, no C++!

 http://www.robg3d.com/2014/01/why-ccp-is-still-using-python-2/
 http://www.pcgamer.com/2013/06/15/eve-online/
I don't play Eve, but in general the challenge in virtual worlds is that you need to do full veracity checking on the server to reduce cheating. You should also hide parts of the model so that only the server knows it. Basically, you have to run the entire sim on the server and only run parts of it on the client for display purposes if you want to reduce cheating without introducing draconian measures that basically takes over the machine (which cannot work if the client runs in the browser). Anyway, at the end of the day, for a freemium game you need to cut server costs because you cannot estimate correctly how much money you make per online user. With a subscription model you are better off and can spend more on hardware. What you can or cannot do, depends on the business model, the market and the game design…
I agree, but keep this is mind: a business model is not carved in stone, it keeps changing, as the market is not a static thing. And this is true also in the programming language field, as the IT universe is not a static thing. I liked the Lang.NEXT panel, especially when Bjarne talked about the real world pressure over C++...
 What I loved about D, from the real beginning, was this:
 pragmatism, pragmatism!
I am pragmatic about this. I have stuff planned that can run on Python on top of Google Datastore on the server and use Dart+WebGL on the client. But if you want a physics based model, user building and fast travelling you have to consider the worst case scenario and you cannot do it in Python or using a disk based database. You need a in-memory database and hit the hardware so that you can take the peaks without ending up with molasses of latency.
If you read carefully, EVE was not designed for the actual number of concurrent users: they was forced to keep changing, to survive the challenges. The worst case scenario is the today worst case scenario. You can't design now for what you think will be the needs in a too much distance future, that's will put your product in the Longhorn cemetery. Things need to be done now, to get the current business opportunity window.
 And after the love, what moved us as a company to adopt it was
 Walter: He is a deeply pragmatic guy!
 Pragmatism is an invaluable asset in business (btw, THAT should
 be stressed in the logo/identity/redesign looooooong thread)
The most valuable factor in business is predictability, opportunities and being better at cutting costs than the competition.
Thinks are a little more complicated than that, but well, at the end, business is all about satisfying the needs of someone else who is free to choose among alternatives. So, turning back into the floating point issue of the thread, what's the most pragmatic move D can take about that floating point performance issue? Take the road that satisfy better the most demanded need asked nowadays by D user base, so speed by default. Satisfy the precision demand with real, but keep this need in an explicit language domain corner: there's no silver bullet.
 Pragmatism in the context of D is community building. Sure, 
 being
 pragmatic about the logo is important, you should encourage
 people using it in different ways because it is a community
 building tool (among many). Like the penguin in Linux being used
 in games etc. Community building means encouraging participation
 and setting direction. If you don't set direction, people will
 sit on the fence waiting for something to happen. Communities
 don't build skeletons, they add meat to the bones.
What I was meaning: "a pragmatic language" is a beautiful business claim, let's stress it: it worked very well for me! --- Paolo
Jul 05 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 5 July 2014 at 13:16:28 UTC, Paolo Invernizzi wrote:
 I agree, but keep this is mind: a business model is not carved 
 in stone, it keeps changing, as the market is not a static 
 thing.
Ok, but for the virtual world side I am more driven by (artistic) model needs than the business side. So I am looking for a solution that fits the requirements.
 And this is true also in the programming language field, as the
 IT universe is not a static thing.
No, but for contractual work I need to be able to add small enhancements 12 months after deployment without adding transition costs. So a static dev environment matters a lot. If a customer expect that an enhancement takes 10 hours to add, I cannot charge for 50 hours. So if the dev environment incurs a transition cost I have to accept the enhancement request at a loss. (App Engine is pretty stable and has a 12 months guarantee, which is on the low side IMO. I think 24 months would be more appropriate.).
 If you read carefully, EVE was not designed for the actual 
 number of concurrent users:
I only glossed over it. I read external analyses of EVE 10 years ago when I studied online worlds. I believe they had some significant performance problems back. But the game model is not really low latency based.
 You can't design now for what you think will be the needs in a
 too much distance future, that's will put your product in the
 Longhorn cemetery. Things need to be done now, to get the 
 current business opportunity window.
I'm not interested in virtual worlds for the business, but for the art of it. So my basic ideas are 10-20 years old and basically just waiting for the technology to catch up. ;^) If I have to nudge the tech to make the last mile, ok, then I might have to do so…
 So, turning back into the floating point issue of the thread,
 what's the most pragmatic move D can take about that floating
 point performance issue?
Provide the tools to specify the constraints, like you do for nogc/safe, but with version support. But I think D should be specified, not by the implementation, but in a paper. And I think the language should be cleaned up a bit, on paper, without thinking about the implementation cost for a specific compiler. Because if the resulting language is a true beauty, then more hands will come to add meat to the bones. I'm not complaining about requiring strict IEEE 754 compliance, I am complaining about requiring it and then saying that it does not matter what the compiler devs do. Because it is obvious that on many platforms you don't get full compliance for special cases without some kind of software emulation/handling.
 What I was meaning: "a pragmatic language" is a beautiful
 business claim, let's stress it: it worked very well for me!
Python is a very pragmatic language, I don't like the dynamic aspects, but it is one of the most pragmatic languages out there. The way I see it now, the most pragmatic solution would be to fork D, clean up the syntax a bit and make it work well for the domain of game servers. I don't need the libraries. Only UDP/TCP. Whether that is cost efficient compared to just using C++, I dunno. But the more I follow the discussions on the D forums, the more I feel that forking will be more productive than spending effort on affecting the current direction (which most probably will not get me what I want).
Jul 05 2014
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 July 2014 15:20, via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Saturday, 5 July 2014 at 13:16:28 UTC, Paolo Invernizzi wrote:
 I agree, but keep this is mind: a business model is not carved in stone,
 it keeps changing, as the market is not a static thing.
Ok, but for the virtual world side I am more driven by (artistic) model needs than the business side. So I am looking for a solution that fits the requirements.
 And this is true also in the programming language field, as the
 IT universe is not a static thing.
No, but for contractual work I need to be able to add small enhancements 12 months after deployment without adding transition costs. So a static dev environment matters a lot. If a customer expect that an enhancement takes 10 hours to add, I cannot charge for 50 hours. So if the dev environment incurs a transition cost I have to accept the enhancement request at a loss. (App Engine is pretty stable and has a 12 months guarantee, which is on the low side IMO. I think 24 months would be more appropriate.).
 If you read carefully, EVE was not designed for the actual number of
 concurrent users:
I only glossed over it. I read external analyses of EVE 10 years ago when I studied online worlds. I believe they had some significant performance problems back. But the game model is not really low latency based.
 You can't design now for what you think will be the needs in a
 too much distance future, that's will put your product in the
 Longhorn cemetery. Things need to be done now, to get the current business
 opportunity window.
I'm not interested in virtual worlds for the business, but for the art of it. So my basic ideas are 10-20 years old and basically just waiting for the technology to catch up. ;^) If I have to nudge the tech to make the last mile, ok, then I might have to do so…
 So, turning back into the floating point issue of the thread,
 what's the most pragmatic move D can take about that floating
 point performance issue?
Provide the tools to specify the constraints, like you do for nogc/safe, but with version support. But I think D should be specified, not by the implementation, but in a paper. And I think the language should be cleaned up a bit, on paper, without thinking about the implementation cost for a specific compiler. Because if the resulting language is a true beauty, then more hands will come to add meat to the bones. I'm not complaining about requiring strict IEEE 754 compliance, I am complaining about requiring it and then saying that it does not matter what the compiler devs do. Because it is obvious that on many platforms you don't get full compliance for special cases without some kind of software emulation/handling.
This is a library problem, not a language problem. In this case std.math uses real everywhere when perhaps it shouldn't.
 What I was meaning: "a pragmatic language" is a beautiful
 business claim, let's stress it: it worked very well for me!
Python is a very pragmatic language, I don't like the dynamic aspects, but it is one of the most pragmatic languages out there.
http://pyd.dsource.org
 The way I see it now, the most pragmatic solution would be to fork D, clean
 up the syntax a bit and make it work well for the domain of game servers. I
 don't need the libraries. Only UDP/TCP. Whether that is cost efficient
 compared to just using C++, I dunno. But the more I follow the discussions
 on the D forums, the more I feel that forking will be more productive than
 spending effort on affecting the current direction (which most probably will
 not get me what I want).
You mean, MiniD? Someone has already done that, years ago.... http://jfbillingsley.com/croc/wiki/Lang/GettingStarted
Jul 05 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 5 July 2014 at 15:09:28 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 This is a library problem, not a language problem.  In this case
 std.math uses real everywhere when perhaps it shouldn't.
If x/y leads to a division by zero trap when it should not, then it isn't a library problem.
 You mean, MiniD?  Someone has already done that, years ago....
No, I meant forking D.
Jul 05 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ola Fosheim Grøstad:

 No, I meant forking D.
There is already Delight and FeepingCreature has created a D-like language. If you fork D you will have lot of fun :-) Keep us updated. Bye, bearophile
Jul 05 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 5 July 2014 at 15:28:00 UTC, bearophile wrote:
 There is already Delight and FeepingCreature has created a 
 D-like language. If you fork D you will have lot of fun :-)
Thanks :) Both Delight and FeepingCreature appears to be alive. I guess that is a good sign.
Jul 05 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ola Fosheim Grøstad:

 Both Delight and FeepingCreature appears to be alive. I guess 
 that is a good sign.
language directive "#light" that switches to a brace-less syntax: http://msdn.microsoft.com/en-us/library/dd233199.aspx but later the light one has become the standard one. Bye, bearophile
Jul 06 2014
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Sunday, 6 July 2014 at 17:19:24 UTC, bearophile wrote:

 language directive "#light" that switches to a brace-less 
 syntax:
I like compact syntax, like the reduction in clutter done with Go. I've been thinking a lot about how to improve the assignments in C-like languages. Seems to me that when it comes to immutable values it makes sense to deal with them in a functional style. I.e. there is no real need to distinguish between a comparison of equality and a defined equality (assignment). Of course, that means boolean contexts have to be made explicit to avoid ambiguity. IMO reducing clutter becomes really important when you use the language for describing content that needs to be modified and extended.
Jul 06 2014
prev sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 5 July 2014 16:13, via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Saturday, 5 July 2014 at 15:09:28 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 This is a library problem, not a language problem.  In this case
 std.math uses real everywhere when perhaps it shouldn't.
If x/y leads to a division by zero trap when it should not, then it isn't a library problem.
Right, it's a quirk of the CPU.
Jul 05 2014
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 5 July 2014 at 16:24:28 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 Right, it's a quirk of the CPU.
It's a precision quirk of floating point that has to be defined, and different CPUs follow different definitions. Within IEEE754 it can of course also differ, since it does not prevent higher precision than specified. http://en.wikipedia.org/wiki/Denormal_number
Jul 05 2014
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 5:48 AM, "Ola Fosheim Grøstad" 
<ola.fosheim.grostad+dlang gmail.com>" wrote:
 I pick the most stable tool for the job. Meaning I usually end up with C,
 conservative use of C++, Python 2.7, Javascript, SQL or XSLT… :-P Rarely D
and
 occasionally Dart (which isn't particularly stable either and is rejected
 beacuase of it) and Php (which is pretty stable).

 It's a matter of priority. If the D maintainers don't care about reaching a
 stable state, at the expense of scope and features, then it will never be the
 best tool for the job. I regret that.
We care a great deal about that. C++, etc., is a much harder tool to get work done with. You'd have to judge that difficulty and work increase against the dealing with imperfections in D. It's a clear win for D.
Jul 04 2014
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, 2014-07-04 at 12:48 +0000, via Digitalmars-d wrote:
[=E2=80=A6]
 I pick the most stable tool for the job. Meaning I usually end up=20
 with C, conservative use of C++, Python 2.7, Javascript, SQL or=20
[=E2=80=A6] That should, of course, have read Python 3.4! --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jul 04 2014
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Saturday, 5 July 2014 at 06:48:23 UTC, Russel Winder via 
Digitalmars-d wrote:
 That should, of course, have read Python 3.4!
Most of my code has to run on App Engine, so I stick to whatever version Google use for all my Python stuff. They had Guido do their db-api a couple of years back so they probably stick with 2.7 for a good reason? Sometimes "stable" means "with known bugs and known work-arounds". ;)
Jul 05 2014
prev sibling parent "Paolo Invernizzi" <paolo.invernizzi no.address> writes:
On Wednesday, 2 July 2014 at 12:24:51 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 2 July 2014 at 12:16:18 UTC, Wanderer wrote:

 D is not even production ready, so why should there be? Who in 
 their right mind would use a language in limbo for building a 
 serious operating system or do embedded work? You need language 
 stability and compiler maturity first.
That's plain wrong: here at SR Labs we are using it in production, and making money over it. --- Paolo
Jul 02 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 29 June 2014 22:45, Russel Winder via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 Hopefully there are points here for pedantry and bloody mindedness…


 On Sat, 2014-06-28 at 18:32 -0700, Walter Bright via Digitalmars-d
 wrote:
 […]
 Keep in mind that D is a systems programming language, and that
implies you get
 access to the hardware types.
On Sun, 2014-06-29 at 12:22 -0700, Walter Bright via Digitalmars-d wrote: […].
 That is not  true with D. D specifies that float and double are IEEE 754 types
 which have specified size and behavior. D's real type is the largest the
 underlying hardware will support.

 D also specifies 'int' is 32 bits, 'long' is 64, and 'byte' is 8, 'short' is
16.
D gives access to the hardware types, and D defines the structure of all those types. The only resolution is that D only works on that hardware where the hardware types are the ones D defines. Thus D only works on a subset of hardware, and can never be ported to hardware where the hardware types differ from those defined by D. So D float and double will not work on IBM 360 unless interpreted, and real would be 128-bit (not IEEE)?
I'm sure it isn't as bad as you describe for floor and double. And if it is, then I can't see GCC (C/C++) working on IBM 360 either, without some out-of-band patches. And so what you allege IBM to have done is a platform problem, not a language one. Support for IBM extended reals is partial, and will improve as PPC is ported to.
 The D real type definitely suffers the C/C++ float and double problem!

 I guess we just hope that all future hardware is IEEE754 compliant.
else static assert(false, "Here's a nickel, kid. Go buy yourself a real computer."); // :)
Jun 29 2014
prev sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Sun, Jun 29, 2014 at 11:18:43PM +0100, Iain Buclaw via Digitalmars-d wrote:
 On 29 June 2014 22:45, Russel Winder via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
[...]
 The D real type definitely suffers the C/C++ float and double
 problem!

 I guess we just hope that all future hardware is IEEE754 compliant.
else static assert(false, "Here's a nickel, kid. Go buy yourself a real computer."); // :)
+1. :-) T -- Debian GNU/Linux: Cray on your desktop.
Jun 29 2014
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 28 June 2014 at 09:07:17 UTC, John Colvin wrote:
 On Saturday, 28 June 2014 at 06:16:51 UTC, Walter Bright wrote:
 On 6/27/2014 10:18 PM, Walter Bright wrote:
 On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically 
 stable/correct and benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Sorry for being so abrupt. FP is important to me - it's not just about performance, it's also about accuracy.
I still maintain that the need for the precision of 80bit reals is a niche demand. Its a very important niche, but it doesn't justify having its relatively extreme requirements be the default. Someone writing a matrix inversion has only themselves to blame if they don't know plenty of numerical analysis and look very carefully at the specifications of all operations they are using. Paying the cost of moving to/from the fpu, missing out on increasingly large SIMD units, these make everyone pay the price. inclusion of the 'real' type in D was a great idea, but std.math should be overloaded for float/double/real so people have the choice where they stand on the performance/precision front.
Would thar make sense to have std.mast and std.fastmath, or something along these lines ?
Jun 28 2014
parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 29 June 2014 10:11, deadalnix via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Saturday, 28 June 2014 at 09:07:17 UTC, John Colvin wrote:
 On Saturday, 28 June 2014 at 06:16:51 UTC, Walter Bright wrote:
 On 6/27/2014 10:18 PM, Walter Bright wrote:
 On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically stable/correct and
 benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Sorry for being so abrupt. FP is important to me - it's not just about performance, it's also about accuracy.
I still maintain that the need for the precision of 80bit reals is a niche demand. Its a very important niche, but it doesn't justify having its relatively extreme requirements be the default. Someone writing a matrix inversion has only themselves to blame if they don't know plenty of numerical analysis and look very carefully at the specifications of all operations they are using. Paying the cost of moving to/from the fpu, missing out on increasingly large SIMD units, these make everyone pay the price. inclusion of the 'real' type in D was a great idea, but std.math should be overloaded for float/double/real so people have the choice where they stand on the performance/precision front.
Would thar make sense to have std.mast and std.fastmath, or something along these lines ?
I've thought this too. std.math and std.numeric maybe? To me, 'fastmath' suggests comfort with approximations/estimates or other techniques in favour of speed, and I don't think the non-'real' version should presume that. It's not that we have a 'normal' one and a 'fast' one. What we have is a 'slow' one, and the other is merely normal; ie, "std.math".
Jun 29 2014
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/27/14, 11:16 PM, Walter Bright wrote:
 On 6/27/2014 10:18 PM, Walter Bright wrote:
 On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically stable/correct
 and benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Sorry for being so abrupt. FP is important to me - it's not just about performance, it's also about accuracy.
The only problem is/would be when the language forces one choice over the other. Both options of maximum performance and maximum precision should be handily accessible to D users. Andrei
Jun 28 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/28/2014 6:49 AM, Andrei Alexandrescu wrote:
 The only problem is/would be when the language forces one choice over the
other.
 Both options of maximum performance and maximum precision should be handily
 accessible to D users.
That's a much more reasonable position than "we should abandon 80 bit reals".
Jun 28 2014
next sibling parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
I think this thread is getting out of hand. The main point was to
get float and double overloads for std.math.

This whole discussion about numeric stability, the naming of
double and float, the state of real.... all of it is a little bit
ridiculous.

Numerical stability is not really related to getting faster
overloads other than the obvious fact that it is a trade off.
Float and double do not need a name change. Real also does not
need a change.

I think this thread needs to refocus on the main point, getting
math overloads for float and double and how to mitigate any
problems that might arise from that.
Jun 28 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/28/14, 6:02 PM, Tofu Ninja wrote:
 I think this thread is getting out of hand. The main point was to
 get float and double overloads for std.math.

 This whole discussion about numeric stability, the naming of
 double and float, the state of real.... all of it is a little bit
 ridiculous.

 Numerical stability is not really related to getting faster
 overloads other than the obvious fact that it is a trade off.
 Float and double do not need a name change. Real also does not
 need a change.

 I think this thread needs to refocus on the main point, getting
 math overloads for float and double and how to mitigate any
 problems that might arise from that.
Yes please. -- Andrei
Jun 28 2014
next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Sat, Jun 28, 2014 at 08:41:24PM -0700, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 6/28/14, 6:02 PM, Tofu Ninja wrote:
[...]
I think this thread needs to refocus on the main point, getting
math overloads for float and double and how to mitigate any
problems that might arise from that.
Yes please. -- Andrei
Let's see the PR! And while we're on the topic, what about working on making std.math CTFE-able? So far, CTFE simply doesn't support fundamental floating-point operations like isInfinity, isNaN, signbit, to name a few, because CTFE does not allow accessing the bit representation of floating-point values. This is a big disappointment for me -- it defeats the power of CTFE by making it unusable if you want to use it to generate pre-calculated tables of values. Perhaps we can introduce some intrinsics for implementing these functions so that they work both in CTFE and at runtime? https://issues.dlang.org/show_bug.cgi?id=3749 Thanks to Iain's hard work on std.math, now we have software implementations for all(?) the basic math functions, so in theory they should be CTFE-able -- except that some functions require access to the floating-point bit representation, which CTFE doesn't support. All it takes is to these primitives, and std.math will be completely CTFE-able -- a big step forward IMHO. T -- Talk is cheap. Whining is actually free. -- Lars Wirzenius
Jun 28 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 29 Jun 2014 05:48, "H. S. Teoh via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 On Sat, Jun 28, 2014 at 08:41:24PM -0700, Andrei Alexandrescu via
Digitalmars-d wrote:
 On 6/28/14, 6:02 PM, Tofu Ninja wrote:
[...]
I think this thread needs to refocus on the main point, getting
math overloads for float and double and how to mitigate any
problems that might arise from that.
Yes please. -- Andrei
Let's see the PR!
I've already raised one (already linked in this thread). More to come!
 And while we're on the topic, what about working on making std.math
 CTFE-able? So far, CTFE simply doesn't support fundamental
 floating-point operations like isInfinity, isNaN, signbit, to name a
 few, because CTFE does not allow accessing the bit representation of
 floating-point values.
As it stands, as soon as the above mentioned PR for Phobos is merged, isNaN and isInfinite on float and double types will be CTFE-able. However that depends on whether or not float->int painting will be replaced with a union.
 This is a big disappointment for me -- it defeats
 the power of CTFE by making it unusable if you want to use it to
 generate pre-calculated tables of values.

 Perhaps we can introduce some intrinsics for implementing these
 functions so that they work both in CTFE and at runtime?

         https://issues.dlang.org/show_bug.cgi?id=3749
CTFE support for accessing basic types in unions - as in painting between all kinds of scalar types, with special support for static arrays (via vectors) should be all that is required. Once CTFE supports that, it won't be difficult to get std.math to be CTFE-certified. :)
 Thanks to Iain's hard work on std.math, now we have software
 implementations for all(?) the basic math functions, so in theory they
 should be CTFE-able -- except that some functions require access to the
 floating-point bit representation, which CTFE doesn't support. All it
 takes is to these primitives, and std.math will be completely CTFE-able
 -- a big step forward IMHO.
The original goal was making std.math non-asm implementations *genuinely* pure/nothrow/ safe for GDC x86, and for other ports like ARM, SPARC so LDC benefits also. Andrei was the one who sold me on the idea if making them CTFE-able. However, I stopped just short of that goal because of this missing feature of DMD - though I did implement it in GDC as proof of concept that it is possible (code not actually published anywhere) There should be a bug report somewhere that I outlined the exact steps in. Regards Iain.
Jun 29 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Sun, Jun 29, 2014 at 08:54:49AM +0100, Iain Buclaw via Digitalmars-d wrote:
 On 29 Jun 2014 05:48, "H. S. Teoh via Digitalmars-d" <
 digitalmars-d puremagic.com> wrote:
 On Sat, Jun 28, 2014 at 08:41:24PM -0700, Andrei Alexandrescu via
Digitalmars-d wrote:
 On 6/28/14, 6:02 PM, Tofu Ninja wrote:
[...]
I think this thread needs to refocus on the main point, getting
math overloads for float and double and how to mitigate any
problems that might arise from that.
Yes please. -- Andrei
Let's see the PR!
I've already raised one (already linked in this thread).
basically identical to my own idea for fixing std.math -- using unions instead of pointer casting. However, without compiler support for repainting scalars in a union, I couldn't get what I needed to work. I'm trying to make atan2 CTFE-able, but it in turn uses isInfinity, isNaN, signbit, and possibly one or two others, and while I managed to hack isInfinity and isNaN, signbit defeated me due to the signedness of NaNs, which cannot be extracted in any other way.
 More to come!
Are you going to implement repainting unions in CTFE? That would be *awesome*. [...]
 Perhaps we can introduce some intrinsics for implementing these
 functions so that they work both in CTFE and at runtime?

         https://issues.dlang.org/show_bug.cgi?id=3749
CTFE support for accessing basic types in unions - as in painting between all kinds of scalar types, with special support for static arrays (via vectors) should be all that is required.
I thought as much. Currently, unions don't support repainting in CTFE, so it doesn't work. I think that's the last hurdle needed, since with repainting everything else can be done in code.
 Once CTFE supports that, it won't be difficult to get std.math to be
 CTFE-certified. :)
[...] Looking forward to that! T -- Why ask rhetorical questions? -- JC
Jun 29 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 29 June 2014 23:20, H. S. Teoh via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Sun, Jun 29, 2014 at 08:54:49AM +0100, Iain Buclaw via Digitalmars-d wrote:
 On 29 Jun 2014 05:48, "H. S. Teoh via Digitalmars-d" <
 digitalmars-d puremagic.com> wrote:
 On Sat, Jun 28, 2014 at 08:41:24PM -0700, Andrei Alexandrescu via
Digitalmars-d wrote:
 On 6/28/14, 6:02 PM, Tofu Ninja wrote:
[...]
I think this thread needs to refocus on the main point, getting
math overloads for float and double and how to mitigate any
problems that might arise from that.
Yes please. -- Andrei
Let's see the PR!
I've already raised one (already linked in this thread).
basically identical to my own idea for fixing std.math -- using unions instead of pointer casting.
Not really. The biggest speed up was from adding float+double overloads for floor, ceil, isNaN and isInfinity. Firstly, the use of a union itself didn't make much of a dent in the speed up. Removing the slow array copy operation did though. Secondly, unions are required for this particular function (floor) because we need to set bits through type-punning, it just wouldn't work casting to a pointer. Regards Iain
Jun 29 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Sun, Jun 29, 2014 at 11:33:20PM +0100, Iain Buclaw via Digitalmars-d wrote:
 On 29 June 2014 23:20, H. S. Teoh via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On Sun, Jun 29, 2014 at 08:54:49AM +0100, Iain Buclaw via Digitalmars-d wrote:
 On 29 Jun 2014 05:48, "H. S. Teoh via Digitalmars-d" <
 digitalmars-d puremagic.com> wrote:
 On Sat, Jun 28, 2014 at 08:41:24PM -0700, Andrei Alexandrescu via
Digitalmars-d wrote:
 On 6/28/14, 6:02 PM, Tofu Ninja wrote:
[...]
I think this thread needs to refocus on the main point,
getting math overloads for float and double and how to
mitigate any problems that might arise from that.
Yes please. -- Andrei
Let's see the PR!
I've already raised one (already linked in this thread).
basically identical to my own idea for fixing std.math -- using unions instead of pointer casting.
Not really. The biggest speed up was from adding float+double overloads for floor, ceil, isNaN and isInfinity. Firstly, the use of a union itself didn't make much of a dent in the speed up. Removing the slow array copy operation did though. Secondly, unions are required for this particular function (floor) because we need to set bits through type-punning, it just wouldn't work casting to a pointer.
[...] I wasn't referring to the speedup (though that is certainly nice), I was talking about making things CTFE-able. What's the status of repainting unions in CTFE? Is there a PR for that yet, or do we need to implement one? T -- People tell me that I'm skeptical, but I don't believe it.
Jun 30 2014
parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Monday, 30 June 2014 at 16:29:08 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 What's the status of repainting unions in CTFE? Is there a PR 
 for that
 yet, or do we need to implement one?


 T
What exactly does "repainting a union" mean? I am not familiar with that phrase, google has not helped me either.
Jun 30 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Mon, Jun 30, 2014 at 05:35:34PM +0000, Tofu Ninja via Digitalmars-d wrote:
 On Monday, 30 June 2014 at 16:29:08 UTC, H. S. Teoh via Digitalmars-d wrote:
What's the status of repainting unions in CTFE? Is there a PR for
that yet, or do we need to implement one?


T
What exactly does "repainting a union" mean? I am not familiar with that phrase, google has not helped me either.
I may have misused the term, perhaps the proper term is "painting"? Anyway, it means to write data of one type to the union, and read out a different type. E.g., write a double into a union of double and ubyte[double.sizeof], and then read out the latter, in order to get at the bit representation of the double without using pointer casting: ubyte[double.sizeof] getRepresentation(double d) { union U { double d; ubyte[double.sizeof] rep; } U u; u.d = d; return u.rep; } (This is a silly example, of course, since in assembly it amounts to a function that just returns its argument. Usually you do something non-trivial with u.rep, such as extract the sign bit or mantissa, and so forth.) Right now, this doesn't work in CTFE (it implicitly type-tags all unions, and raises an error when you try to read out a different type than you wrote in). But this kind of type-punning is needed to implement some of the fundamental floating-point operations. T -- Question authority. Don't ask why, just do it.
Jun 30 2014
parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Monday, 30 June 2014 at 17:49:52 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 I may have misused the term, perhaps the proper term is 
 "painting"?

 Anyway, it means to write data of one type to the union, and 
 read out a
 different type. E.g., write a double into a union of double and
 ubyte[double.sizeof], and then read out the latter, in order to 
 get at
 the bit representation of the double without using pointer 
 casting
Oh, ok that make sense. I have never heard that called any form of painting before. I never realized that had a name at all really, just thought it was a thing you did with unions. Thank for the clarification.
Jun 30 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 11:06 AM, Tofu Ninja wrote:
 Oh, ok that make sense. I have never heard that called any form of painting
 before. I never realized that had a name at all really, just thought it was a
 thing you did with unions. Thank for the clarification.
The notion is to "paint" a type onto data.
Jun 30 2014
parent reply "Temtaime" <temtaime gmail.com> writes:
And my opinion is that real should be deprecated and removed in 
the future.
Double is enough.
If your application depends on float-point accuracy you have 
problems.
Jun 30 2014
next sibling parent reply "Chris Cain" <zshazz gmail.com> writes:
On Monday, 30 June 2014 at 19:42:34 UTC, Temtaime wrote:
 And my opinion is that real should be deprecated and removed in 
 the future.
 Double is enough.
 If your application depends on float-point accuracy you have 
 problems.
I think that real should be deprecated and removed in favor of a library quadruple (binary128) and/or library "real" type. Plus I think having some form of decimal64 and decimal128 types (despite being non-native and slower) would be highly appreciated as well. I'm siding with Walter that precision is important and we should make it easy to get more precision at the cost of speed (of course, fast float/double ops should be fully supported as well). Obviously better algorithms that require less precision is the ideal approach, but we shouldn't assume that users will want to spend time on better algorithms. Offering easy-to-accomplish accuracy is a good feature as long as the difficult-to-accomplish better accuracy with higher performance is also possible. I think having even more precise types you can count on for different situations is better. I dunno if that will actually change, but maybe we could implement the library versions and see if Walter ends up liking that approach better.
Jun 30 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Mon, Jun 30, 2014 at 09:06:26PM +0000, Chris Cain via Digitalmars-d wrote:
[...]
 I think that real should be deprecated and removed in favor of a
 library quadruple (binary128) and/or library "real" type. Plus I think
 having some form of decimal64 and decimal128 types (despite being
 non-native and slower) would be highly appreciated as well. I'm siding
 with Walter that precision is important and we should make it easy to
 get more precision at the cost of speed (of course, fast float/double
 ops should be fully supported as well).  Obviously better algorithms
 that require less precision is the ideal approach, but we shouldn't
 assume that users will want to spend time on better algorithms.
 Offering easy-to-accomplish accuracy is a good feature as long as the
 difficult-to-accomplish better accuracy with higher performance is
 also possible.
 
 I think having even more precise types you can count on for different
 situations is better. I dunno if that will actually change, but maybe
 we could implement the library versions and see if Walter ends up
 liking that approach better.
How do you implement 80-bit reals in the library? T -- Some ideas are so stupid that only intellectuals could believe them. -- George Orwell
Jun 30 2014
parent reply "Chris Cain" <zshazz gmail.com> writes:
On Monday, 30 June 2014 at 21:51:22 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 How do you implement 80-bit reals in the library?
Is it a legitimate problem to do so? My feeling is that it should be possible if it's possible to implement it in C or asm since it's possible to do everything in D that is possible to do in C or asm.
Jun 30 2014
parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, Jul 01, 2014 at 01:21:11AM +0000, Chris Cain via Digitalmars-d wrote:
 On Monday, 30 June 2014 at 21:51:22 UTC, H. S. Teoh via Digitalmars-d wrote:
How do you implement 80-bit reals in the library?
Is it a legitimate problem to do so? My feeling is that it should be possible if it's possible to implement it in C or asm since it's possible to do everything in D that is possible to do in C or asm.
It will be a pain, because you will need asm blocks to implement x87 instructions. And you won't be able to simulate optimizations that the compiler can -- like common subexpression factoring, eliminating redundant loads, etc.. Those are precisely the kind of things that you need compiler support for, in order to have acceptable performance. (Well, you *could* in theory implement these optimizations using CTFE to produce asm string mixins, but you'd have to use string DSLs instead of language-level expressions in order for this to work. Or you'd have to use expression templates, which will become an unmaintainable mess. Plus you'd be reinventing much of what the compiler already does for you -- register allocation, codegen, etc.. Basically, all that work just to move reals outside the compiler seems to be misdirected effort to me.) T -- If you think you are too small to make a difference, try sleeping in a closed room with a mosquito. -- Jan van Steenbergen
Jun 30 2014
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 12:42 PM, Temtaime wrote:
 And my opinion is that real should be deprecated and removed in the future.
 Double is enough.
D would no longer be compatible with C if that were done.
Jun 30 2014
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/29/2014 02:42 AM, Walter Bright wrote:
 On 6/28/2014 6:49 AM, Andrei Alexandrescu wrote:
 The only problem is/would be when the language forces one choice over
 the other.
 Both options of maximum performance and maximum precision should be
 handily
 accessible to D users.
That's a much more reasonable position than "we should abandon 80 bit reals".
If that is what you were arguing against, I don't think this was actually suggested.
Jun 28 2014
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/28/14, 5:42 PM, Walter Bright wrote:
 On 6/28/2014 6:49 AM, Andrei Alexandrescu wrote:
 The only problem is/would be when the language forces one choice over
 the other.
 Both options of maximum performance and maximum precision should be
 handily
 accessible to D users.
That's a much more reasonable position than "we should abandon 80 bit reals".
Awesome! -- Andrei
Jun 28 2014
prev sibling parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 28 June 2014 16:16, Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 6/27/2014 10:18 PM, Walter Bright wrote:
 On 6/27/2014 4:10 AM, John Colvin wrote:
 *The number of algorithms that are both numerically stable/correct and
 benefit
 significantly from > 64bit doubles is very small.
To be blunt, baloney. I ran into these problems ALL THE TIME when doing professional numerical work.
Sorry for being so abrupt. FP is important to me - it's not just about performance, it's also about accuracy.
Well, here's the thing then. Consider that 'real' is only actually supported on only a single (long deprecated!) architecture. I think it's reasonable to see that 'real' is not actually an fp type. It's more like an auxiliary type, which just happens to be supported via a completely different (legacy) set of registers on x64 (most arch's don't support it at all). In x64's case, it is deprecated for over a decade now, and may be removed from the hardware at some unknown time. The moment that x64 processors decide to stop supporting 32bit code, the x87 will go away, and those opcodes will likely be emulated or microcoded. Interacting real<->float/double means register swapping through memory. It should be treated the same as float<->simd; they are distinct (on most arch's). For my money, x87 can only be considered, at best, a coprocessor (a slow one!), which may or may not exist. Software written today (10+ years after the hardware was deprecated) should probably even consider introducing runtime checks to see if the hardware is even present before making use of it. It's fine to offer a great precise extended precision library, but I don't think it can be _the_ standard math library which is used by everyone in virtually all applications. It's not a defined part of the architecture, it's slow, and it will probably go away in the future. It's the same situation with SIMD; on x64, the SIMD unit and the FPU are the same unit, but I don't think it's reasonable to design all the API's around that assumption. Most processors separate the SIMD unit from the FPU, and the language decisions reflect that. We can't make the language treat SIMD just like an FPU extensions on account of just one single architecture... although in that case, the argument would be even more compelling since x64 is actually current and active.
Jun 29 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 8:22 PM, Manu via Digitalmars-d wrote:
 Well, here's the thing then. Consider that 'real' is only actually
 supported on only a single (long deprecated!) architecture.
It's news to me that x86, x86-64, etc., are deprecated, despite being used to run pretty much all desktops and laptops and even servers. The 80 bit reals are also part of the C ABI for Linux, OSX, and FreeBSD, 32 and 64 bit.
 I think it's reasonable to see that 'real' is not actually an fp type.
I find that a bizarre statement.
 It's more like an auxiliary type, which just happens to be supported
 via a completely different (legacy) set of registers on x64 (most
 arch's don't support it at all).
The SIMD registers are also a "completely different set of registers".
 In x64's case, it is deprecated for over a decade now, and may be
 removed from the hardware at some unknown time. The moment that x64
 processors decide to stop supporting 32bit code, the x87 will go away,
 and those opcodes will likely be emulated or microcoded.
 Interacting real<->float/double means register swapping through
 memory. It should be treated the same as float<->simd; they are
 distinct (on most arch's).
Since they are part of the 64 bit C ABI, that would seem to be in the category of "nevah hoppen".
 It's the same situation with SIMD; on x64, the SIMD unit and the FPU
 are the same unit, but I don't think it's reasonable to design all the
 API's around that assumption. Most processors separate the SIMD unit
 from the FPU, and the language decisions reflect that. We can't make
 the language treat SIMD just like an FPU extensions on account of just
 one single architecture... although in that case, the argument would
 be even more compelling since x64 is actually current and active.
Intel has yet to remove any SIMD instructions.
Jun 29 2014
next sibling parent reply Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 30 June 2014 14:15, Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 6/29/2014 8:22 PM, Manu via Digitalmars-d wrote:
 Well, here's the thing then. Consider that 'real' is only actually
 supported on only a single (long deprecated!) architecture.
It's news to me that x86, x86-64, etc., are deprecated, despite being used to run pretty much all desktops and laptops and even servers. The 80 bit reals are also part of the C ABI for Linux, OSX, and FreeBSD, 32 and 64 bit.
x86_64 and x86 are different architectures, and they have very different ABI's. Nobody is manufacturing x86 (exclusive) cpu's. Current x86_64 cpu's maintain a backwards compatibility mode, but that's not a part of the x86-64 spec, and may go away when x86_64 is deemed sufficiently pervasive and x86 sufficiently redundant.
 I think it's reasonable to see that 'real' is not actually an fp type.
I find that a bizarre statement.
Well, it's not an fp type as implemented by the standard fp architecture of any cpu except x86, which is becoming less relevant with each passing day.
 It's more like an auxiliary type, which just happens to be supported
 via a completely different (legacy) set of registers on x64 (most
 arch's don't support it at all).
The SIMD registers are also a "completely different set of registers".
Correct, so they are deliberately treated separately. I argued for strong separation between simd and float, and you agreed.
 In x64's case, it is deprecated for over a decade now, and may be
 removed from the hardware at some unknown time. The moment that x64
 processors decide to stop supporting 32bit code, the x87 will go away,
 and those opcodes will likely be emulated or microcoded.
 Interacting real<->float/double means register swapping through
 memory. It should be treated the same as float<->simd; they are
 distinct (on most arch's).
Since they are part of the 64 bit C ABI, that would seem to be in the category of "nevah hoppen".
Not in windows. You say they are in linux? I don't know. "Intel started discouraging the use of x87 with the introduction of the P4 in late 2000. AMD deprecated x87 since the K8 in 2003, as x86-64 is defined with SSE2 support; VIA’s C7 has supported SSE2 since 2005. In 64-bit versions of Windows, x87 is deprecated for user-mode, and prohibited entirely in kernel-mode." How do you distinguish x87 double and xmm double in C? The only way I know to access x87 is with inline asm.
 It's the same situation with SIMD; on x64, the SIMD unit and the FPU
 are the same unit, but I don't think it's reasonable to design all the
 API's around that assumption. Most processors separate the SIMD unit
 from the FPU, and the language decisions reflect that. We can't make
 the language treat SIMD just like an FPU extensions on account of just
 one single architecture... although in that case, the argument would
 be even more compelling since x64 is actually current and active.
Intel has yet to remove any SIMD instructions.
Huh? I think you misunderstood my point. I'm saying that fpu/simd units are distinct, and they are distanced by the type system in order to respect that separation.
Jun 29 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/29/2014 9:38 PM, Manu via Digitalmars-d wrote:
 It's news to me that x86, x86-64, etc., are deprecated, despite being used
 to run pretty much all desktops and laptops and even servers. The 80 bit
 reals are also part of the C ABI for Linux, OSX, and FreeBSD, 32 and 64 bit.
x86_64 and x86 are different architectures, and they have very different ABI's. Nobody is manufacturing x86 (exclusive) cpu's. Current x86_64 cpu's maintain a backwards compatibility mode, but that's not a part of the x86-64 spec, and may go away when x86_64 is deemed sufficiently pervasive and x86 sufficiently redundant.
It's still part of the C ABI for both 32 and 64 bit code.
 Correct, so they are deliberately treated separately.
 I argued for strong separation between simd and float, and you agreed.
floats & doubles are implemented using SIMD instructions.
 Since they are part of the 64 bit C ABI, that would seem to be in the
 category of "nevah hoppen".
Not in windows.
Correct.
 You say they are in linux? I don't know.
Since you don't believe me, I recommend looking it up. The document is entitled "System V Application Binary Interface AMD64 Architecture Processor Supplement" Furthermore, just try using "long double" on Linux, and disassemble the resulting code.
 How do you distinguish x87 double and xmm double in C?
You don't. It's a compiler implementation issue.
 The only way I know to access x87 is with inline asm.
I suggest using "long double" on Linux and look at the compiler output. You don't have to believe me - use gcc or clang.
 Huh? I think you misunderstood my point. I'm saying that fpu/simd
 units are distinct, and they are distanced by the type system in order
 to respect that separation.
I think that's not correct. There's nothing in the C Standard that says you have to implement float semantics with any particular FPU, nor does the C type system distinguish FPUs.
Jun 29 2014
next sibling parent reply "ed" <growlercab gmail.com> writes:
On Monday, 30 June 2014 at 06:21:49 UTC, Walter Bright wrote:

When precision is an issue we always choose a software solution. 
This has been my experience in both geophysics and medical device 
development. It is cheaper, faster (dev. time), and better tested 
than anything we would develop within a release time frame.

But D "real" is a winner IMO. At my last workplace we ported some 
geophysics C++ apps to D for fun. The apps required more 
precision than double could offer and relied on GMP/MPFR. It was 
a nice surprise when we found the extra bits in D's real were 
enough for some of these apps to be correct without GMP/MPFR and 
gave a real performance boost (pun intended!).

We targeted x86/x86_64 desktops and clusters running linux 
(windows and MAC on desktops as well).

We did not consider the lack of IBM 360 support to be an issue 
when porting to D :-P


Cheers,
ed
Jun 30 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 12:35 AM, ed wrote:
 On Monday, 30 June 2014 at 06:21:49 UTC, Walter Bright wrote:

 When precision is an issue we always choose a software solution. This has been
 my experience in both geophysics and medical device development. It is cheaper,
 faster (dev. time), and better tested than anything we would develop within a
 release time frame.

 But D "real" is a winner IMO. At my last workplace we ported some geophysics
C++
 apps to D for fun. The apps required more precision than double could offer and
 relied on GMP/MPFR. It was a nice surprise when we found the extra bits in D's
 real were enough for some of these apps to be correct without GMP/MPFR and gave
 a real performance boost (pun intended!).

 We targeted x86/x86_64 desktops and clusters running linux (windows and MAC on
 desktops as well).
Good to know!
 We did not consider the lack of IBM 360 support to be an issue when porting to
D
 :-P
The 360 is almost as auld as I am!
Jun 30 2014
prev sibling parent reply dennis luehring <dl.soluz gmx.net> writes:
Am 30.06.2014 08:21, schrieb Walter Bright:
 The only way I know to access x87 is with inline asm.
I suggest using "long double" on Linux and look at the compiler output. You don't have to believe me - use gcc or clang.
gcc.godbolt.org clang 3.4.1 -O3 int main(int argc, char** argv) { return ((long double)argc/12345.6789); } asm: .LCPI0_0: movl %edi, -8(%rsp) fildl -8(%rsp) fdivl .LCPI0_0(%rip) fnstcw -10(%rsp) movw -10(%rsp), %ax fldcw -10(%rsp) movw %ax, -10(%rsp) fistpl -4(%rsp) fldcw -10(%rsp) movl -4(%rsp), %eax ret
Jun 30 2014
parent dennis luehring <dl.soluz gmx.net> writes:
Am 30.06.2014 18:30, schrieb dennis luehring:
 Am 30.06.2014 08:21, schrieb Walter Bright:
 The only way I know to access x87 is with inline asm.
I suggest using "long double" on Linux and look at the compiler output. You don't have to believe me - use gcc or clang.
gcc.godbolt.org clang 3.4.1 -O3
better this int main(int argc, char** argv) { return argc * 12345.6789L; } .LCPI0_0: .quad -4546745350290602879 .short 16396 .zero 6 movl %edi, -8(%rsp) fldt .LCPI0_0(%rip) fimull -8(%rsp) fnstcw -10(%rsp) movw -10(%rsp), %ax fldcw -10(%rsp) movw %ax, -10(%rsp) fistpl -4(%rsp) fldcw -10(%rsp) movl -4(%rsp), %eax ret
Jun 30 2014
prev sibling parent reply "Don" <x nospam.com> writes:
On Monday, 30 June 2014 at 04:15:46 UTC, Walter Bright wrote:
 On 6/29/2014 8:22 PM, Manu via Digitalmars-d wrote:
 Well, here's the thing then. Consider that 'real' is only 
 actually
 supported on only a single (long deprecated!) architecture.
 In x64's case, it is deprecated for over a decade now, and may 
 be
 removed from the hardware at some unknown time. The moment 
 that x64
 processors decide to stop supporting 32bit code, the x87 will 
 go away,
 and those opcodes will likely be emulated or microcoded.
 Interacting real<->float/double means register swapping through
 memory. It should be treated the same as float<->simd; they are
 distinct (on most arch's).
Since they are part of the 64 bit C ABI, that would seem to be in the category of "nevah hoppen".
What I think is highly likely is that it will only have legacy support, with such awful performance that it never makes sense to use them. For example, the speed of 80-bit and 64-bit calculations in x87 used to be identical. But on recent Intel CPUs, the 80-bit operations run at half the speed of the 64 bit operations. They are already partially microcoded. For me, a stronger argument is that you can get *higher* precision using doubles, in many cases. The reason is that FMA gives you an intermediate value with 128 bits of precision; it's available in SIMD but not on x87. So, if we want to use the highest precision supported by the hardware, that does *not* mean we should always use 80 bits. I've experienced this in CTFE, where the calculations are currently done in 80 bits, I've seen cases where the 64-bit runtime results were more accurate, because of those 128 bit FMA temporaries. 80 bits are not enough!!
Jun 30 2014
next sibling parent "ed" <growlercab gmail.com> writes:
On Monday, 30 June 2014 at 07:21:00 UTC, Don wrote:
 On Monday, 30 June 2014 at 04:15:46 UTC, Walter Bright wrote:
 On 6/29/2014 8:22 PM, Manu via Digitalmars-d wrote:
 Well, here's the thing then. Consider that 'real' is only 
 actually
 supported on only a single (long deprecated!) architecture.
 In x64's case, it is deprecated for over a decade now, and 
 may be
 removed from the hardware at some unknown time. The moment 
 that x64
 processors decide to stop supporting 32bit code, the x87 will 
 go away,
 and those opcodes will likely be emulated or microcoded.
 Interacting real<->float/double means register swapping 
 through
 memory. It should be treated the same as float<->simd; they 
 are
 distinct (on most arch's).
Since they are part of the 64 bit C ABI, that would seem to be in the category of "nevah hoppen".
What I think is highly likely is that it will only have legacy support, with such awful performance that it never makes sense to use them. For example, the speed of 80-bit and 64-bit calculations in x87 used to be identical. But on recent Intel CPUs, the 80-bit operations run at half the speed of the 64 bit operations. They are already partially microcoded. For me, a stronger argument is that you can get *higher* precision using doubles, in many cases. The reason is that FMA gives you an intermediate value with 128 bits of precision; it's available in SIMD but not on x87. So, if we want to use the highest precision supported by the hardware, that does *not* mean we should always use 80 bits. I've experienced this in CTFE, where the calculations are currently done in 80 bits, I've seen cases where the 64-bit runtime results were more accurate, because of those 128 bit FMA temporaries. 80 bits are not enough!!
This is correct and we use this now for some time critical code that requires high precision. But anything non-time critical (~80%-85% of our code) we simply use a software solution when precision becomes an issue. It is here that I think the extra bits in D real can be enough to get a performance gain. But I won't argue with you think I'm wrong. I'm only basing this on anecdotal evidence of what I saw from 5-6 apps ported from C++ to D :-) Cheers, ed
Jun 30 2014
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 12:20 AM, Don wrote:
 What I think is highly likely is that it will only have legacy support, with
 such awful performance that it never makes sense to use them. For example, the
 speed of 80-bit and 64-bit calculations in x87 used to be identical. But on
 recent Intel CPUs, the 80-bit operations run at half the speed of the 64 bit
 operations. They are already partially microcoded.

 For me, a stronger argument is that you can get *higher* precision using
 doubles, in many cases. The reason is that FMA gives you an intermediate value
 with 128 bits of precision; it's available in SIMD but not on x87.

 So, if we want to use the highest precision supported by the hardware, that
does
 *not* mean we should always use 80 bits.

 I've experienced this in CTFE, where the calculations are currently done in 80
 bits, I've seen cases where the 64-bit runtime results were more accurate,
 because of those 128 bit FMA temporaries. 80 bits are not enough!!
I did not know this. It certainly adds another layer of nuance - as the higher level of precision will only apply as long as one can keep the value in a register.
Jun 30 2014
parent reply "Don" <x nospam.com> writes:
On Monday, 30 June 2014 at 16:54:17 UTC, Walter Bright wrote:
 On 6/30/2014 12:20 AM, Don wrote:
 What I think is highly likely is that it will only have legacy 
 support, with
 such awful performance that it never makes sense to use them. 
 For example, the
 speed of 80-bit and 64-bit calculations in x87 used to be 
 identical. But on
 recent Intel CPUs, the 80-bit operations run at half the speed 
 of the 64 bit
 operations. They are already partially microcoded.

 For me, a stronger argument is that you can get *higher* 
 precision using
 doubles, in many cases. The reason is that FMA gives you an 
 intermediate value
 with 128 bits of precision; it's available in SIMD but not on 
 x87.

 So, if we want to use the highest precision supported by the 
 hardware, that does
 *not* mean we should always use 80 bits.

 I've experienced this in CTFE, where the calculations are 
 currently done in 80
 bits, I've seen cases where the 64-bit runtime results were 
 more accurate,
 because of those 128 bit FMA temporaries. 80 bits are not 
 enough!!
I did not know this. It certainly adds another layer of nuance - as the higher level of precision will only apply as long as one can keep the value in a register.
Yes, it's complicated. The interesting thing is that there are no 128 bit registers. The temporaries exist only while the FMA operation is in progress. You cannot even preserve them between consecutive FMA operations. An important consequence is that allowing intermediate calculations to be performed at higher precision than the operands, is crucial, and applies outside of x86. This is something we've got right. But it's not possible to say that "the intermediate calculations are done at the precision of 'real'". This is the semantics which I think we currently have wrong. Our model is too simplistic. On modern x86, calculations on float operands may have intermediate calculations done at only 32 bits (if using straight SSE), 80 bits (if using x87), or 64 bits (if using float FMA). And for double operands, they may be 64 bits, 80 bits, or 128 bits. Yet, in the FMA case, non-FMA operations will be performed at lower precision. It's entirely possible for all three intermediate precisions to be active at the same time! I'm not sure that we need to change anything WRT code generation. But I think our style recommendations aren't quite right. And we have at least one missing primitive operation (discard all excess precision).
Jul 01 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/1/2014 3:26 AM, Don wrote:
 Yes, it's complicated. The interesting thing is that there are no 128 bit
 registers. The temporaries exist only while the FMA operation is in progress.
 You cannot even preserve them between consecutive FMA operations.

 An important consequence is that allowing intermediate calculations to be
 performed at higher precision than the operands, is crucial, and applies
outside
 of x86. This is something we've got right.

 But it's not possible to say that "the intermediate calculations are done at
the
 precision of 'real'". This is the semantics which I think we currently have
 wrong. Our model is too simplistic.

 On modern x86, calculations on float operands may have intermediate
calculations
 done at only 32 bits (if using straight SSE), 80 bits (if using x87), or 64
bits
 (if using float FMA). And for double operands, they may be 64 bits, 80 bits, or
 128 bits.
 Yet, in the FMA case, non-FMA operations will be performed at lower precision.
 It's entirely possible for all three intermediate precisions to be active at
the
 same time!

 I'm not sure that we need to change anything WRT code generation. But I think
 our style recommendations aren't quite right. And we have at least one missing
 primitive operation (discard all excess precision).
What do you recommend?
Jul 01 2014
parent reply "Don" <x nospam.com> writes:
On Tuesday, 1 July 2014 at 17:00:30 UTC, Walter Bright wrote:
 On 7/1/2014 3:26 AM, Don wrote:
 Yes, it's complicated. The interesting thing is that there are 
 no 128 bit
 registers. The temporaries exist only while the FMA operation 
 is in progress.
 You cannot even preserve them between consecutive FMA 
 operations.

 An important consequence is that allowing intermediate 
 calculations to be
 performed at higher precision than the operands, is crucial, 
 and applies outside
 of x86. This is something we've got right.

 But it's not possible to say that "the intermediate 
 calculations are done at the
 precision of 'real'". This is the semantics which I think we 
 currently have
 wrong. Our model is too simplistic.

 On modern x86, calculations on float operands may have 
 intermediate calculations
 done at only 32 bits (if using straight SSE), 80 bits (if 
 using x87), or 64 bits
 (if using float FMA). And for double operands, they may be 64 
 bits, 80 bits, or
 128 bits.
 Yet, in the FMA case, non-FMA operations will be performed at 
 lower precision.
 It's entirely possible for all three intermediate precisions 
 to be active at the
 same time!

 I'm not sure that we need to change anything WRT code 
 generation. But I think
 our style recommendations aren't quite right. And we have at 
 least one missing
 primitive operation (discard all excess precision).
What do you recommend?
It needs some thought. But some things are clear. Definitely, discarding excess precision is a crucial operation. C and C++ tried to do it implicitly with "sequence points", but that kills optimisation possibilities so much that compilers don't respect it. I think it's actually quite similar to write barriers in multithreaded programming. C got it wrong, but we're currently in an even worse situation because it doesn't necessarily happen at all. We need a builtin operation -- and not in std.math, this is as crucial as addition, and it's purely a signal to the optimiser. It's very similar to a casting operation. I wonder if we can do it as an attribute? .exact_float, .restrict_float, .force_float, .spill_float or something similar? With D's current floating point semantics, it's actually impossible to write correct floating-point code. Everything that works right now, is technically only working by accident. But if we get this right, we can have very nice semantics for when things like FMA are allowed to happen -- essentially the optimiser would have free reign between these explicit discard_excess_precision sequence points. After that, I'm a bit less sure. It does seem to me that we're trying to make 'real' do double-duty as meaning both "x87 80 bit floating-point number" and also as something like a storage class that is specific to double: "compiler, don't discard excess precision". Which are both useful concepts, but aren't identical. The two concepts did coincide on x86 32-bit, but they're different on x86-64. I think we need to distinguish the two. Ideally, I think we'd have a __real80 type. On x86 32 bit this would be the same as 'real', while on x86-64 __real80 would be available but probably 'real' would alias to double. But I'm a lot less certain about this.
Jul 02 2014
next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 2 July 2014 09:53, Don via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Tuesday, 1 July 2014 at 17:00:30 UTC, Walter Bright wrote:
 On 7/1/2014 3:26 AM, Don wrote:
 Yes, it's complicated. The interesting thing is that there are no 128 bit
 registers. The temporaries exist only while the FMA operation is in
 progress.
 You cannot even preserve them between consecutive FMA operations.

 An important consequence is that allowing intermediate calculations to be
 performed at higher precision than the operands, is crucial, and applies
 outside
 of x86. This is something we've got right.

 But it's not possible to say that "the intermediate calculations are done
 at the
 precision of 'real'". This is the semantics which I think we currently
 have
 wrong. Our model is too simplistic.

 On modern x86, calculations on float operands may have intermediate
 calculations
 done at only 32 bits (if using straight SSE), 80 bits (if using x87), or
 64 bits
 (if using float FMA). And for double operands, they may be 64 bits, 80
 bits, or
 128 bits.
 Yet, in the FMA case, non-FMA operations will be performed at lower
 precision.
 It's entirely possible for all three intermediate precisions to be active
 at the
 same time!

 I'm not sure that we need to change anything WRT code generation. But I
 think
 our style recommendations aren't quite right. And we have at least one
 missing
 primitive operation (discard all excess precision).
What do you recommend?
It needs some thought. But some things are clear. Definitely, discarding excess precision is a crucial operation. C and C++ tried to do it implicitly with "sequence points", but that kills optimisation possibilities so much that compilers don't respect it. I think it's actually quite similar to write barriers in multithreaded programming. C got it wrong, but we're currently in an even worse situation because it doesn't necessarily happen at all. We need a builtin operation -- and not in std.math, this is as crucial as addition, and it's purely a signal to the optimiser. It's very similar to a casting operation. I wonder if we can do it as an attribute? .exact_float, .restrict_float, .force_float, .spill_float or something similar? With D's current floating point semantics, it's actually impossible to write correct floating-point code. Everything that works right now, is technically only working by accident. But if we get this right, we can have very nice semantics for when things like FMA are allowed to happen -- essentially the optimiser would have free reign between these explicit discard_excess_precision sequence points.
Fixing this is the goal I assume. :) --- import std.stdio; void test(double x, double y) { double y2 = x + 1.0; if (y != y2) writeln("error"); // Prints 'error' under -O2 } void main() { immutable double x = .012; // Removing 'immutable' and it works. double y = x + 1.0; test(x, y); } ---
 After that, I'm a bit less sure. It does seem to me that we're trying to
 make 'real' do double-duty as meaning both "x87 80 bit floating-point
 number" and also as something like a storage class that is specific to
 double: "compiler, don't discard excess precision". Which are both useful
 concepts, but aren't identical. The two concepts did coincide on x86 32-bit,
 but they're different on x86-64. I think we need to distinguish the two.

 Ideally, I think we'd have a __real80 type. On x86 32 bit this would be the
 same as 'real', while on x86-64 __real80 would be available but probably
 'real' would alias to double. But I'm a lot less certain about this.
There are flags for that in gdc: -mlong-double-64 -mlong-double-80 -mlong-double-128
Jul 02 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 1:53 AM, Don wrote:
 Definitely, discarding excess precision is a crucial operation. C and C++ tried
 to do it implicitly with "sequence points", but that kills optimisation
 possibilities so much that compilers don't respect it. I think it's actually
 quite similar to write barriers in multithreaded programming. C got it wrong,
 but we're currently in an even worse situation because it doesn't necessarily
 happen at all.

 We need a builtin operation -- and not in std.math, this is as crucial as
 addition, and it's purely a signal to the optimiser. It's very similar to a
 casting operation. I wonder if we can do it as an attribute?  .exact_float,
 .restrict_float, .force_float, .spill_float or something similar?

 With D's current floating point semantics, it's actually impossible to write
 correct floating-point code. Everything that works right now, is technically
 only working by accident.

 But if we get this right, we can have very nice semantics for when things like
 FMA are allowed to happen -- essentially the optimiser would have free reign
 between these explicit discard_excess_precision sequence points.
This is easily handled without language changes by putting a couple builtin functions in druntime - roundToFloat() and roundToDouble().
 Ideally, I think we'd have a __real80 type. On x86 32 bit this would be the
same
 as 'real', while on x86-64 __real80 would be available but probably 'real'
would
 alias to double. But I'm a lot less certain about this.
I'm afraid that would not only break most D programs, but also interoperability with C.
Jul 02 2014
next sibling parent reply "Sean Kelly" <sean invisibleduck.org> writes:
On Wednesday, 2 July 2014 at 20:37:37 UTC, Walter Bright wrote:
 On 7/2/2014 1:53 AM, Don wrote:
 Ideally, I think we'd have a __real80 type. On x86 32 bit this 
 would be the same as 'real', while on x86-64 __real80 would be 
 available but probably 'real' would alias to double. But I'm a 
 lot less certain about this.
I'm afraid that would not only break most D programs, but also interoperability with C.
Could you explain this? I didn't think we used 'real' to interface with C at all. We might need a type to match 'long double' in C, but what that is is already exceedingly variable. This would probably be another case for a special alias like we have for c_long.
Jul 02 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 2:33 PM, Sean Kelly wrote:
 On Wednesday, 2 July 2014 at 20:37:37 UTC, Walter Bright wrote:
 I'm afraid that would not only break most D programs, but also
 interoperability with C.
Could you explain this? I didn't think we used 'real' to interface with C at all. We might need a type to match 'long double' in C, but what that is is already exceedingly variable. This would probably be another case for a special alias like we have for c_long.
C long double == D real for 32 and 64 bit OSX, Linux, and FreeBSD.
Jul 02 2014
parent reply "Sean Kelly" <sean invisibleduck.org> writes:
On Wednesday, 2 July 2014 at 21:44:17 UTC, Walter Bright wrote:
 On 7/2/2014 2:33 PM, Sean Kelly wrote:
 On Wednesday, 2 July 2014 at 20:37:37 UTC, Walter Bright wrote:
 I'm afraid that would not only break most D programs, but also
 interoperability with C.
Could you explain this? I didn't think we used 'real' to interface with C at all. We might need a type to match 'long double' in C, but what that is is already exceedingly variable. This would probably be another case for a special alias like we have for c_long.
C long double == D real for 32 and 64 bit OSX, Linux, and FreeBSD.
And it's 'double double' on PPC and 128 bit quad on SPARC. Assuming D targets those platforms, what will be the behavior there? From my perspective, it seems like 'real' in D is utterly non-portable given its definition. I can see maybe using it in some cases if I knew I was targeting a specific architecture where the added precision was helpful, but for general purpose programming I'd always either use 'double' or some library-based type for extended precision, simply to have some assurance that my result would be predictable. Am I wrong in this?
Jul 02 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 3:15 PM, Sean Kelly wrote:
 On Wednesday, 2 July 2014 at 21:44:17 UTC, Walter Bright wrote:
 C long double == D real for 32 and 64 bit OSX, Linux, and FreeBSD.
And it's 'double double' on PPC and 128 bit quad on SPARC. Assuming D targets those platforms, what will be the behavior there?
Per the D spec, 'real' will be the longest type supported by the native hardware.
   From my perspective, it seems like 'real' in D is utterly
 non-portable given its definition.  I can see maybe using it in
 some cases if I knew I was targeting a specific architecture
 where the added precision was helpful, but for general purpose
 programming I'd always either use 'double' or some library-based
 type for extended precision, simply to have some assurance that
 my result would be predictable.  Am I wrong in this?
D is a systems programming language. That means it should have access to the hardware supported types. Portability is not the only goal - especially if that means "least common denominator". People pay money for more powerful chips, and they'll want to use them. Not only that, a marquee feature of D is interoperability with C. We'd need an AWFULLY good reason to throw that under the bus.
Jul 02 2014
next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Jul 02, 2014 at 05:03:47PM -0700, Walter Bright via Digitalmars-d wrote:
[...]
 D is a systems programming language. That means it should have access
 to the hardware supported types. Portability is not the only goal -
 especially if that means "least common denominator". People pay money
 for more powerful chips, and they'll want to use them.
What should we do in the case of hardware that offers strange hardware types, like a hypothetical 48-bit floating point type? Should D offer a built-in type for that purpose, even if it only exists on a single chip that's used by 0.01% of the community?
 Not only that, a marquee feature of D is interoperability with C. We'd
 need an AWFULLY good reason to throw that under the bus.
I'm not sure I understand how removing support 80-bit floats hurts interoperability with C? I thought none of the standard C float types map to the x87 80-bit float? (I'm not opposed to keeping real as 80-bit on x87, but I just don't understand what this has to do with C interoperability.) T -- In order to understand recursion you must first understand recursion.
Jul 02 2014
next sibling parent reply "Sean Kelly" <sean invisibleduck.org> writes:
On Thursday, 3 July 2014 at 01:13:13 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 I'm not sure I understand how removing support 80-bit floats 
 hurts interoperability with C? I thought none of the standard C 
 float types map to the x87 80-bit float?
The C spec never says anything specific about representation because it's meant to target anything, but the x86 and AMD64 ABIs basically say that "long double" is 80-bit for calculations. The x86 spec says that the type is stored in 96 bits though, and the AMD64 spec says they're stored in 128 bits for alignment purposes. I'm still unclear whether we're aiming for C interoperability or hardware support though, based on Walter's remark about SPARC and PPC. There, 'long double' is represented differently but is not backed by specialized hardware, so I'm guessing D would make 'real' 64-bits on these platforms and break compatibility with C. So... I guess we really do need a special alias for C compatibility, and this can map to whatever intrinsic type the applicable compiler supports for that platform.
Jul 02 2014
next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3 Jul 2014 04:50, "Sean Kelly via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 On Thursday, 3 July 2014 at 01:13:13 UTC, H. S. Teoh via Digitalmars-d
wrote:
 I'm not sure I understand how removing support 80-bit floats hurts
interoperability with C? I thought none of the standard C float types map to the x87 80-bit float?
 The C spec never says anything specific about representation because it's
meant to target anything, but the x86 and AMD64 ABIs basically say that "long double" is 80-bit for calculations. The x86 spec says that the type is stored in 96 bits though, and the AMD64 spec says they're stored in 128 bits for alignment purposes.
 I'm still unclear whether we're aiming for C interoperability or hardware
support though, based on Walter's remark about SPARC and PPC. There, 'long double' is represented differently but is not backed by specialized hardware, so I'm guessing D would make 'real' 64-bits on these platforms and break compatibility with C. So... I guess we really do need a special alias for C compatibility, and this can map to whatever intrinsic type the applicable compiler supports for that platform. I take the spec to mean that I can map float, double, and real to the native C types for float, double, and long double - or in jargon terms, the native single, double, and extended (or quad if the user or backend requests it) types. Certainly I have implemented my bits of std.math with real == double and real == quad in mind. PPC will have to wait, but it is easy enough to identify doubledouble reals in CTFE. Iain.
Jul 02 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 8:48 PM, Sean Kelly wrote:
 I'm still unclear whether we're aiming for C interoperability or hardware
 support though, based on Walter's remark about SPARC and PPC.  There, 'long
 double' is represented differently but is not backed by specialized hardware,
so
 I'm guessing D would make 'real' 64-bits on these platforms and break
 compatibility with C.  So... I guess we really do need a special alias for C
 compatibility, and this can map to whatever intrinsic type the applicable
 compiler supports for that platform.
What is unclear about being able to call a C function declared as: int foo(long double r); from D?
Jul 02 2014
next sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 02 Jul 2014 23:56:21 -0700
Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 On 7/2/2014 8:48 PM, Sean Kelly wrote:
 I'm still unclear whether we're aiming for C interoperability or
 hardware support though, based on Walter's remark about SPARC and
 PPC.  There, 'long double' is represented differently but is not
 backed by specialized hardware, so I'm guessing D would make 'real'
 64-bits on these platforms and break compatibility with C.  So... I
 guess we really do need a special alias for C compatibility, and
 this can map to whatever intrinsic type the applicable compiler
 supports for that platform.
What is unclear about being able to call a C function declared as: int foo(long double r); from D?
I don't think that there's anything unclear about that. The problem is that if real is supposed to be the largest hardware supported floating point type, then that doesn't necessarily match long double. It happens to on x86 and x86_64, but it doesn't on other architectures. So, is real the same as C's long double, or is it the same as the largest floating point type supported by the hardware? We have erroneously treated them as the same thing, because they happen to be the same thing on x86 hardware. But D needs to work on more than just x86 and x86_64, even if dmd doesn't. We already have aliases such as c_long to deal with C types. I don't think that it would be all that big a deal to make it so that real was specifically the largest supported hardware type and then have c_long_double for interacting with C. - Jonathan M Davis
Jul 03 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/3/2014 3:49 AM, Jonathan M Davis via Digitalmars-d wrote:
 I don't think that there's anything unclear about that. The problem is that if
 real is supposed to be the largest hardware supported floating point type,
 then that doesn't necessarily match long double. It happens to on x86 and
 x86_64, but it doesn't on other architectures.
As it turns out, C compilers tend to use long double for that. So there's no issue. In any case, it's up to the person porting the D compiler to that platform to make these decisions. For another case, D for Win64 maps real to 80 bits, despite VC++ mapping long double to 64 bits. This is compatible with the D spec, because you are still able to call C functions typed as "int foo(long double r)" because D's double works for that. I think that some common sense on a case by case basis for each platform should work fine.
Jul 03 2014
next sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Thu, 03 Jul 2014 12:45:17 -0700
Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 On 7/3/2014 3:49 AM, Jonathan M Davis via Digitalmars-d wrote:
 I don't think that there's anything unclear about that. The problem
 is that if real is supposed to be the largest hardware supported
 floating point type, then that doesn't necessarily match long
 double. It happens to on x86 and x86_64, but it doesn't on other
 architectures.
As it turns out, C compilers tend to use long double for that. So there's no issue. In any case, it's up to the person porting the D compiler to that platform to make these decisions. For another case, D for Win64 maps real to 80 bits, despite VC++ mapping long double to 64 bits. This is compatible with the D spec, because you are still able to call C functions typed as "int foo(long double r)" because D's double works for that. I think that some common sense on a case by case basis for each platform should work fine.
I'm fine with real varying from platform to platform depending on what makes sense for that platform, but I think that it should be clear what real is generally supposed to be (e.g. the largest floating point type that the hardware supports), but unless it's _guaranteed_ that real be the same as long double, I would strongly argue in favor of having an alias for long double rather than using real directly (much as it will likely be an alias to real in most cases). We already do that with c_long. - Jonathan M Davis
Jul 03 2014
parent "Sean Kelly" <sean invisibleduck.org> writes:
On Thursday, 3 July 2014 at 21:01:43 UTC, Jonathan M Davis via
Digitalmars-d wrote:
 I'm fine with real varying from platform to platform depending 
 on what makes sense for that platform, but I think that it 
 should be clear what real is generally supposed to be (e.g. the 
 largest floating point type that the hardware supports), but 
 unless it's _guaranteed_ that real be the same as long double, 
 I would strongly argue in favor of having an alias for long 
 double rather than using real directly (much as it will likely 
 be an alias to real in most cases). We already do that with 
 c_long.
I'm inclined to agree. From what's been said, I suspect that on SPARC, 'real' would be an alias of 'double', and c_long_double would be an alias of some intrinsic type provided by the compiler, since there is no D equivalent for the IEEE 754 binary128 type. The alternative, making c_long_double a struct used for marshaling data into and out of the C format, doesn't seem terribly appealing.
Jul 03 2014
prev sibling parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Thu, 3 Jul 2014 14:01:23 -0700
Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 I'm fine with real varying from platform to platform depending on
 what makes sense for that platform, but I think that it should be
 clear what real is generally supposed to be (e.g. the largest
 floating point type that the hardware supports), but unless it's
 _guaranteed_ that real be the same as long double, I would strongly
 argue in favor of having an alias for long double rather than using
 real directly (much as it will likely be an alias to real in most
 cases). We already do that with c_long.
Here: https://github.com/D-Programming-Language/druntime/pull/863 - Jonathan M Davis
Jul 04 2014
prev sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3 July 2014 11:49, Jonathan M Davis via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Wed, 02 Jul 2014 23:56:21 -0700
 Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 On 7/2/2014 8:48 PM, Sean Kelly wrote:
 I'm still unclear whether we're aiming for C interoperability or
 hardware support though, based on Walter's remark about SPARC and
 PPC.  There, 'long double' is represented differently but is not
 backed by specialized hardware, so I'm guessing D would make 'real'
 64-bits on these platforms and break compatibility with C.  So... I
 guess we really do need a special alias for C compatibility, and
 this can map to whatever intrinsic type the applicable compiler
 supports for that platform.
What is unclear about being able to call a C function declared as: int foo(long double r); from D?
I don't think that there's anything unclear about that. The problem is that if real is supposed to be the largest hardware supported floating point type, then that doesn't necessarily match long double. It happens to on x86 and x86_64, but it doesn't on other architectures. So, is real the same as C's long double, or is it the same as the largest floating point type supported by the hardware? We have erroneously treated them as the same thing, because they happen to be the same thing on x86 hardware. But D needs to work on more than just x86 and x86_64, even if dmd doesn't.
The spec should be clearer on that. The language should respect the long double ABI of the platform it is targeting - so if the compiler is targeting a real=96bit system, but the max supported on the chip is 128bit, the compiler should *still* map real to the 96bit long doubles, unless explicitly told otherwise on the command-line. The same goes to other ABI aspects of real, for instance, if you are targeting an ABI where scalar 64bit operations are done in Neon, then the compiler adheres to that (though I'd hope that people stick to defaults and not do this, because the cost of moving data from core registers to neon is high). Regards Iain
Jul 03 2014
parent reply "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Thursday, 3 July 2014 at 11:21:34 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 The spec should be clearer on that.  The language should 
 respect the long double ABI of the platform it is targeting
 - so if the compiler is targeting a real=96bit system, but
 the max supported on the  chip is 128bit, the compiler should
 *still* map real to the 96bit long doubles, unless explicitly
 told otherwise on the command-line.
This would be a change in the standard, no? "The long double ABI of the target platform" is not necessarily the same as the current definition of real as the largest hardware-supported floating-point type. I can't help but feel that this is another case where the definition of real in the D spec, and its practical use in the implementation, have wound up in conflict because of assumptions made relative to x86, where it's simply a nice coincidence that the largets hardware-supported FP and the long double type happen to be the same.
Jul 03 2014
parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 3 July 2014 14:51, Joseph Rushton Wakeling via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Thursday, 3 July 2014 at 11:21:34 UTC, Iain Buclaw via Digitalmars-d
 wrote:
 The spec should be clearer on that.  The language should respect the long
 double ABI of the platform it is targeting
 - so if the compiler is targeting a real=96bit system, but
 the max supported on the  chip is 128bit, the compiler should
 *still* map real to the 96bit long doubles, unless explicitly
 told otherwise on the command-line.
This would be a change in the standard, no? "The long double ABI of the target platform" is not necessarily the same as the current definition of real as the largest hardware-supported floating-point type. I can't help but feel that this is another case where the definition of real in the D spec, and its practical use in the implementation, have wound up in conflict because of assumptions made relative to x86, where it's simply a nice coincidence that the largets hardware-supported FP and the long double type happen to be the same.
It's also a handy coincidence that for many platforms the targets largest supported FP and *double* type happen to be the same too.
Jul 03 2014
parent reply "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Thursday, 3 July 2014 at 14:26:51 UTC, Iain Buclaw via 
Digitalmars-d wrote:
 It's also a handy coincidence that for many platforms the 
 targets
 largest supported FP and *double* type happen to be the same 
 too.
Out of curiosity, how is C "long double" interpreted on those platforms? Just doesn't exist, or is interpreted as the same as double? What's concerning me here is that you've posted at least one example platform where the C long double is _not_ the same as the largest FP type. Now, it makes sense to me that the spec _could_ be, "real == largest hardware-supported FP type", and it makes sense that the spec could be, "real == C long double for the platform". But it seems quite apparent that it can't mean both, and that there needs to be a firm decision about which we want it to be.
Jul 04 2014
parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 4 Jul 2014 10:40, "Joseph Rushton Wakeling via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 On Thursday, 3 July 2014 at 14:26:51 UTC, Iain Buclaw via Digitalmars-d
wrote:
 It's also a handy coincidence that for many platforms the targets
 largest supported FP and *double* type happen to be the same too.
Out of curiosity, how is C "long double" interpreted on those platforms?
Just doesn't exist, or is interpreted as the same as double?

Same as double.

 What's concerning me here is that you've posted at least one example
platform where the C long double is _not_ the same as the largest FP type.
 Now, it makes sense to me that the spec _could_ be, "real == largest
hardware-supported FP type", and it makes sense that the spec could be, "real == C long double for the platform". But it seems quite apparent that it can't mean both, and that there needs to be a firm decision about which we want it to be. It's whatever you configure it to be. Essentially, I want to give porters maximum flexibility on this. Iain.
Jul 04 2014
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/2/2014 6:11 PM, H. S. Teoh via Digitalmars-d wrote:
 What should we do in the case of hardware that offers strange hardware
 types, like a hypothetical 48-bit floating point type? Should D offer a
 built-in type for that purpose, even if it only exists on a single chip
 that's used by 0.01% of the community?
I'd leave that decision up to the guy implementing the D compiler for that chip.
 Not only that, a marquee feature of D is interoperability with C. We'd
 need an AWFULLY good reason to throw that under the bus.
I'm not sure I understand how removing support 80-bit floats hurts interoperability with C? I thought none of the standard C float types map to the x87 80-bit float? (I'm not opposed to keeping real as 80-bit on x87, but I just don't understand what this has to do with C interoperability.)
For the 4th time in this thread, the C ABI for x86 32 and 64 bit OSX, Linux, and FreeBSD maps "long double" to 80 bit reals. How can you call a C function: int foo(long double r); ??
Jul 02 2014
prev sibling next sibling parent reply "Sean Kelly" <sean invisibleduck.org> writes:
On Thursday, 3 July 2014 at 06:56:20 UTC, Walter Bright wrote:
 On 7/2/2014 8:48 PM, Sean Kelly wrote:
 I'm still unclear whether we're aiming for C interoperability 
 or hardware
 support though, based on Walter's remark about SPARC and PPC.  
 There, 'long
 double' is represented differently but is not backed by 
 specialized hardware, so
 I'm guessing D would make 'real' 64-bits on these platforms 
 and break
 compatibility with C.  So... I guess we really do need a 
 special alias for C
 compatibility, and this can map to whatever intrinsic type the 
 applicable
 compiler supports for that platform.
What is unclear about being able to call a C function declared as: int foo(long double r); from D?
This: On Thursday, 3 July 2014 at 00:03:47 UTC, Walter Bright wrote:
 On 7/2/2014 3:15 PM, Sean Kelly wrote:
 On Wednesday, 2 July 2014 at 21:44:17 UTC, Walter Bright wrote:
 C long double == D real for 32 and 64 bit OSX, Linux, and 
 FreeBSD.
And it's 'double double' on PPC and 128 bit quad on SPARC. Assuming D targets those platforms, what will be the behavior there?
Per the D spec, 'real' will be the longest type supported by the native hardware.
Jul 03 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/3/2014 8:36 AM, Sean Kelly wrote:
 Per the D spec, 'real' will be the longest type supported by the native
hardware.
It's not necessary that real be long double - but it is necessary that long double be callable from D. Case in point: long double on Win64 is accessible with D's "double", but D also supports 80 bit "real".
Jul 03 2014
parent reply "Tofu Ninja" <emmons0 purdue.edu> writes:
On Thursday, 3 July 2014 at 19:47:32 UTC, Walter Bright wrote:
 On 7/3/2014 8:36 AM, Sean Kelly wrote:
 Per the D spec, 'real' will be the longest type supported by 
 the native hardware.
It's not necessary that real be long double - but it is necessary that long double be callable from D. Case in point: long double on Win64 is accessible with D's "double", but D also supports 80 bit "real".
That makes it seem like we are compatible by accident rather than by design.
Jul 03 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/3/2014 1:30 PM, Tofu Ninja wrote:
 On Thursday, 3 July 2014 at 19:47:32 UTC, Walter Bright wrote:
 On 7/3/2014 8:36 AM, Sean Kelly wrote:
 Per the D spec, 'real' will be the longest type supported by the native
 hardware.
It's not necessary that real be long double - but it is necessary that long double be callable from D. Case in point: long double on Win64 is accessible with D's "double", but D also supports 80 bit "real".
That makes it seem like we are compatible by accident rather than by design.
?? I see nothing wrong with it, and it was on purpose.
Jul 03 2014
prev sibling next sibling parent reply "Don" <x nospam.com> writes:
On Thursday, 3 July 2014 at 00:03:47 UTC, Walter Bright wrote:
 On 7/2/2014 3:15 PM, Sean Kelly wrote:
 On Wednesday, 2 July 2014 at 21:44:17 UTC, Walter Bright wrote:
 C long double == D real for 32 and 64 bit OSX, Linux, and 
 FreeBSD.
And it's 'double double' on PPC and 128 bit quad on SPARC. Assuming D targets those platforms, what will be the behavior there?
Per the D spec, 'real' will be the longest type supported by the native hardware.
This is the problem. If that is the case, it is USELESS. We *must* change that definition. What is "the longest type supported by the native hardware"? I don't know what that means, and I don't think it even makes sense. For example, Sparc has 128-bit quads, but they only have partial support. Effectively. they are emulated. Why on earth would you want to use an emulated type on some machines, but not on others? Perhaps the intention was "the largest precision you can get for free, without sacrificing speed" then that's not clearly defined. On x86-32, that was indeed 80 bits. But on other systems it doesn't have an obvious answer. On x86-64 it's not that simple. Nor on PPC or Sparc.
Jul 04 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 3:38 AM, Don wrote:
 What is "the longest type supported by the native hardware"? I don't know what
 that means, and I don't think it even makes sense.
Most of the time, it is quite clear.
 For example, Sparc has 128-bit quads, but they only have partial support.
 Effectively. they are emulated. Why on earth would you want to use an emulated
 type on some machines, but not on others?
Emulation is not native support.
 Perhaps the intention was "the largest precision you can get for free, without
 sacrificing speed" then that's not clearly defined. On x86-32, that was indeed
 80 bits. But on other systems it doesn't have an obvious answer.
 On x86-64 it's not that simple. Nor on PPC or Sparc.
Yes, there is some degree of subjectivity on some platforms. I don't see a good reason for hamstringing the compiler dev with legalese for Platform X with legalese that isn't quite the right thing to do for X. I think the intention of the spec is clear, and the compiler implementor can be relied on to exercise good judgement.
Jul 04 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 4 July 2014 at 17:05:16 UTC, Walter Bright wrote:
 On 7/4/2014 3:38 AM, Don wrote:
 What is "the longest type supported by the native hardware"? I 
 don't know what
 that means, and I don't think it even makes sense.
Most of the time, it is quite clear.
 For example, Sparc has 128-bit quads, but they only have 
 partial support.
 Effectively. they are emulated. Why on earth would you want to 
 use an emulated
 type on some machines, but not on others?
Emulation is not native support.
 Perhaps the intention was "the largest precision you can get 
 for free, without
 sacrificing speed" then that's not clearly defined. On x86-32, 
 that was indeed
 80 bits. But on other systems it doesn't have an obvious 
 answer.
 On x86-64 it's not that simple. Nor on PPC or Sparc.
Yes, there is some degree of subjectivity on some platforms. I don't see a good reason for hamstringing the compiler dev with legalese for Platform X with legalese that isn't quite the right thing to do for X. I think the intention of the spec is clear, and the compiler implementor can be relied on to exercise good judgement.
Who are these "compiler implementers"? Are you actually suggesting that, for example, ldc and gdc would seperately decide
Jul 04 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 10:42 AM, John Colvin wrote:
 Who are these "compiler implementers"?
Whoever decides to implement D for a particular platform.
 Are you actually suggesting that, for example, ldc and gdc would seperately
decide
I am confident they will exercise good judgement in making their implementation of D as useful as practical.
Jul 04 2014
prev sibling parent "Don" <x nospam.com> writes:
On Friday, 4 July 2014 at 17:05:16 UTC, Walter Bright wrote:
 On 7/4/2014 3:38 AM, Don wrote:
 What is "the longest type supported by the native hardware"? I 
 don't know what
 that means, and I don't think it even makes sense.
Most of the time, it is quite clear.
 For example, Sparc has 128-bit quads, but they only have 
 partial support.
 Effectively. they are emulated. Why on earth would you want to 
 use an emulated
 type on some machines, but not on others?
Emulation is not native support.
I think the only difference it makes is performance. But there is not very much difference in performance between double-double, and implementations using microcode. Eg PowerPC double-doubles operations require fewer clock cycles than x87 operations on 286.
 Perhaps the intention was "the largest precision you can get 
 for free, without
 sacrificing speed" then that's not clearly defined. On x86-32, 
 that was indeed
 80 bits. But on other systems it doesn't have an obvious 
 answer.
 On x86-64 it's not that simple. Nor on PPC or Sparc.
Yes, there is some degree of subjectivity on some platforms. I don't see a good reason for hamstringing the compiler dev with legalese for Platform X with legalese that isn't quite the right thing to do for X.
I agree. But I think we can achieve the same outcome while providing more semantic guarantees to the programmer.
 I think the intention of the spec is clear, and the compiler 
 implementor can be relied on to exercise good judgement.
The problem is that the developer cannot write code without knowing the semantics. For example, one of the original motivations for having 80-bit floats on the x87 was that for many functions, they give you correctly-rounded results for 'double' precision. If you don't have 80-bit reals, then you need to use far more complicated algorithms. If your code needs to work on a system with only 64 bit reals, then you have to do the hard work. Something I've come to realize, was that William Kahan's work was done in a world before generic programming. He had constraints that we don't have. Our metaprogramming system gives us great tools to get the highest accuracy and performance out of any processor. We can easily cope with the messy reality of real-world systems, we don't need to follow Java in pretending they are all the same. This is something we're good at! A 'real' type that has system-dependent semantics is a poor-man's generics. Take a look at std.math, and see all the instances of 'static if (real.mant_dig == '. Pretty clearly, 'real' is acting as if it were a template parameter. And my experience is that any code which doesn't treat 'real' as a template parameter, is probably incorrect. I think we should acknowledge this.
Jul 08 2014
prev sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Walter Bright"  wrote in message news:lp26l3$qlk$1 digitalmars.com...

 Per the D spec, 'real' will be the longest type supported by the native 
 hardware.
So if you were targeting a processor with only soft-float real would be undefined? Fixing the widths of the integers was a great idea, and we really should have done the same with the floating point types. We could easily have a library alias for what real currently means.
 Not only that, a marquee feature of D is interoperability with C. We'd 
 need an AWFULLY good reason to throw that under the bus.
Unfortunately it's a useless definition for portable interop with C++. real needs to always match the size and mangling of long double unless you want to stick workarounds all over the bindings. We have related problems with char/char/char and long/longlong/size_t, but luckily relatively few interfaces actually use long double.
Jul 04 2014
next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 4 Jul 2014 13:10, "Daniel Murphy via Digitalmars-d" <
digitalmars-d puremagic.com> wrote:
 "Walter Bright"  wrote in message news:lp26l3$qlk$1 digitalmars.com...


 Per the D spec, 'real' will be the longest type supported by the native
hardware.
 So if you were targeting a processor with only soft-float real would be
undefined? Fixing the widths of the integers was a great idea, and we really should have done the same with the floating point types. We could easily have a library alias for what real currently means.

FP types are fixed.  float is 32bit, double 64bit.

 Not only that, a marquee feature of D is interoperability with C. We'd
need an AWFULLY good reason to throw that under the bus.
 Unfortunately it's a useless definition for portable interop with C++.
real needs to always match the size and mangling of long double unless you want to stick workarounds all over the bindings. We have related problems with char/char/char and long/longlong/size_t, but luckily relatively few interfaces actually use long double. What 's the mangling problem with long double? There's only *one* long double.
Jul 04 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d" <digitalmars-d puremagic.com> wrote in 
message news:mailman.3265.1404477916.2907.digitalmars-d puremagic.com...

 FP types are fixed.  float is 32bit, double 64bit.
That's 2/3.
 What 's the mangling problem with long double? There's only *one* long 
 double.
long double may not be the same size as D's real, eg in msvc it's 64-bit. You can still still call these functions from D using double in C, but the mangling will not match in C++.
Jul 04 2014
next sibling parent reply Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 4 July 2014 14:01, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Iain Buclaw via Digitalmars-d" <digitalmars-d puremagic.com> wrote in
 message news:mailman.3265.1404477916.2907.digitalmars-d puremagic.com...


 FP types are fixed.  float is 32bit, double 64bit.
That's 2/3.
 What 's the mangling problem with long double? There's only *one* long
 double.
' long double may not be the same size as D's real, eg in msvc it's 64-bit. You can still still call these functions from D using double in C, but the mangling will not match in C++.
You're confusing long double with size_t. I did a cursory look up msvc++ mangling, and long double is always 'O'. The itanium spec says that long double is 'e' - unless 128bits in which case it is 'g'. Iain.
Jul 04 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Iain Buclaw via Digitalmars-d"  wrote in message 
news:mailman.3268.1404486824.2907.digitalmars-d puremagic.com...

 You're confusing long double with size_t.  I did a cursory look up
 msvc++ mangling, and long double is always 'O'.  The itanium spec says
 that long double is 'e' - unless 128bits in which case it is 'g'.
Yes, so msvc++ has two 64-bit floating types with different manglings, and D has one. D does not have a type that can be used to match long double's mangling with msvc.
Jul 04 2014
parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 4 July 2014 17:31, Daniel Murphy via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 "Iain Buclaw via Digitalmars-d"  wrote in message
 news:mailman.3268.1404486824.2907.digitalmars-d puremagic.com...


 You're confusing long double with size_t.  I did a cursory look up
 msvc++ mangling, and long double is always 'O'.  The itanium spec says
 that long double is 'e' - unless 128bits in which case it is 'g'.
Yes, so msvc++ has two 64-bit floating types with different manglings, and D has one. D does not have a type that can be used to match long double's mangling with msvc.
No, msvc++ has one mangle type. Itanium has two, but you're never going to run into a situation where there's a conflict because long double can't be both 80bit and 128bit at the same time!
Jul 04 2014
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 6:01 AM, Daniel Murphy wrote:
 long double may not be the same size as D's real, eg in msvc it's 64-bit. You
 can still still call these functions from D using double in C, but the mangling
 will not match in C++.
You are correct in that VC++ mangles double as 'N' and long double as 'O' but both are implemented as doubles. This means that: void foo(long double d); is callable from D if it is compiled as C, but not as C++. This is not a language lawyer problem, as D isn't guaranteed to support all C++ mangling. As a practical problem, it would be pretty rare (since such code usually provides double overloads), and if it still was a problem a bit of adapter C++ code (a 1 liner) can be written.
Jul 04 2014
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/4/2014 5:06 AM, Daniel Murphy wrote:
 "Walter Bright"  wrote in message news:lp26l3$qlk$1 digitalmars.com...

 Per the D spec, 'real' will be the longest type supported by the native
hardware.
So if you were targeting a processor with only soft-float real would be undefined? Fixing the widths of the integers was a great idea, and we really should have done the same with the floating point types. We could easily have a library alias for what real currently means.
Again, I expect the implementor for Platform X to be able to make a solid judgement on what to do for that platform that makes the most sense.
 Not only that, a marquee feature of D is interoperability with C. We'd need an
 AWFULLY good reason to throw that under the bus.
Unfortunately it's a useless definition for portable interop with C++. real needs to always match the size and mangling of long double unless you want to stick workarounds all over the bindings. We have related problems with char/char/char and long/longlong/size_t,
Such problems disappear when common sense is applied.
 but luckily relatively few interfaces actually use long double.
I really do not understand what the big problem is. It's trivial to interface with C code on Linux that accepts long doubles on all platforms D currently supports.
Jul 04 2014
prev sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 2 July 2014 21:37, Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 7/2/2014 1:53 AM, Don wrote:
 Definitely, discarding excess precision is a crucial operation. C and C++
 tried
 to do it implicitly with "sequence points", but that kills optimisation
 possibilities so much that compilers don't respect it. I think it's
 actually
 quite similar to write barriers in multithreaded programming. C got it
 wrong,
 but we're currently in an even worse situation because it doesn't
 necessarily
 happen at all.

 We need a builtin operation -- and not in std.math, this is as crucial as
 addition, and it's purely a signal to the optimiser. It's very similar to
 a
 casting operation. I wonder if we can do it as an attribute?
 .exact_float,
 .restrict_float, .force_float, .spill_float or something similar?

 With D's current floating point semantics, it's actually impossible to
 write
 correct floating-point code. Everything that works right now, is
 technically
 only working by accident.

 But if we get this right, we can have very nice semantics for when things
 like
 FMA are allowed to happen -- essentially the optimiser would have free
 reign
 between these explicit discard_excess_precision sequence points.
This is easily handled without language changes by putting a couple builtin functions in druntime - roundToFloat() and roundToDouble().
 Ideally, I think we'd have a __real80 type. On x86 32 bit this would be
 the same
 as 'real', while on x86-64 __real80 would be available but probably 'real'
 would
 alias to double. But I'm a lot less certain about this.
I'm afraid that would not only break most D programs, but also interoperability with C.
I think it could work with a very small selective list of operations. ie: - NegExp - CmpExp - CallExp to core.math intrinsics. Regards Iain.
Jul 02 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/30/14, 2:20 AM, Don wrote:
 For me, a stronger argument is that you can get *higher* precision using
 doubles, in many cases. The reason is that FMA gives you an intermediate
 value with 128 bits of precision; it's available in SIMD but not on x87.

 So, if we want to use the highest precision supported by the hardware,
 that does *not* mean we should always use 80 bits.

 I've experienced this in CTFE, where the calculations are currently done
 in 80 bits, I've seen cases where the 64-bit runtime results were more
 accurate, because of those 128 bit FMA temporaries. 80 bits are not
 enough!!
Interesting. Maybe we should follow a simple principle - define overloads and intrinsic operations such that real is only used if (a) requested explicitly (b) it brings about an actual advantage. I.e. most of the time not using real in user code means it's never real throughout. Andrei
Jun 30 2014
next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Mon, Jun 30, 2014 at 05:18:43PM -0500, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 6/30/14, 2:20 AM, Don wrote:
For me, a stronger argument is that you can get *higher* precision
using doubles, in many cases. The reason is that FMA gives you an
intermediate value with 128 bits of precision; it's available in SIMD
but not on x87.

So, if we want to use the highest precision supported by the
hardware, that does *not* mean we should always use 80 bits.

I've experienced this in CTFE, where the calculations are currently
done in 80 bits, I've seen cases where the 64-bit runtime results
were more accurate, because of those 128 bit FMA temporaries. 80 bits
are not enough!!
Interesting. Maybe we should follow a simple principle - define overloads and intrinsic operations such that real is only used if (a) requested explicitly (b) it brings about an actual advantage. I.e. most of the time not using real in user code means it's never real throughout.
[...] Iain's PR to provide overloads of std.math functions for float/double has already been merged, so all that remains is for float literals to default to double unless suffixed with L, or contain too many digits to accurately represent in double. T -- Never step over a puddle, always step around it. Chances are that whatever made it is still dripping.
Jun 30 2014
next sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Monday, 30 June 2014 at 22:44:44 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 Iain's PR to provide overloads of std.math functions for 
 float/double
 has already been merged, so all that remains […]
Plus all the other functions in std.math, plus a way to provide efficient implementations depending on the target instruction set (compiler intrinsics). David
Jun 30 2014
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/30/2014 3:43 PM, H. S. Teoh via Digitalmars-d wrote:
 Iain's PR to provide overloads of std.math functions for float/double
 has already been merged, so all that remains is for float literals to
 default to double unless suffixed with L,
They already do.
 or contain too many digits to accurately represent in double.
This won't work predictably. Heck, 0.3 is not accurately representable as a double.
Jun 30 2014
prev sibling parent reply dennis luehring <dl.soluz gmx.net> writes:
Am 01.07.2014 00:18, schrieb Andrei Alexandrescu:
 On 6/30/14, 2:20 AM, Don wrote:
 For me, a stronger argument is that you can get *higher* precision using
 doubles, in many cases. The reason is that FMA gives you an intermediate
 value with 128 bits of precision; it's available in SIMD but not on x87.

 So, if we want to use the highest precision supported by the hardware,
 that does *not* mean we should always use 80 bits.

 I've experienced this in CTFE, where the calculations are currently done
 in 80 bits, I've seen cases where the 64-bit runtime results were more
 accurate, because of those 128 bit FMA temporaries. 80 bits are not
 enough!!
Interesting. Maybe we should follow a simple principle - define overloads and intrinsic operations such that real is only used if (a) requested explicitly (b) it brings about an actual advantage.
gcc seems to use GMP for (all) its compiletime calculations - is this for cross-compile unification of calculation results or just for better result at all - or both?
Jun 30 2014
next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 1 July 2014 06:34, dennis luehring via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 Am 01.07.2014 00:18, schrieb Andrei Alexandrescu:

 On 6/30/14, 2:20 AM, Don wrote:
 For me, a stronger argument is that you can get *higher* precision using
 doubles, in many cases. The reason is that FMA gives you an intermediate
 value with 128 bits of precision; it's available in SIMD but not on x87.

 So, if we want to use the highest precision supported by the hardware,
 that does *not* mean we should always use 80 bits.

 I've experienced this in CTFE, where the calculations are currently done
 in 80 bits, I've seen cases where the 64-bit runtime results were more
 accurate, because of those 128 bit FMA temporaries. 80 bits are not
 enough!!
Interesting. Maybe we should follow a simple principle - define overloads and intrinsic operations such that real is only used if (a) requested explicitly (b) it brings about an actual advantage.
gcc seems to use GMP for (all) its compiletime calculations - is this for cross-compile unification of calculation results or just for better result at all - or both?
More cross-compilation where the host has less precision than the target. But at the same time they wouldn't use GMP if it didn't produce accurate results. :)
Jul 01 2014
prev sibling parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"dennis luehring"  wrote in message news:loth9o$2arl$1 digitalmars.com... 

 gcc seems to use GMP for (all) its compiletime calculations - is this 
 for cross-compile unification of calculation results or just for better 
 result at all - or both?
To make the gcc build process more complicated.
Jul 01 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/27/2014 3:50 AM, Manu via Digitalmars-d wrote:
 Totally agree.
 Maintaining commitment to deprecated hardware which could be removed
 from the silicone at any time is a bit of a problem looking forwards.
 Regardless of the decision about whether overloads are created, at
 very least, I'd suggest x64 should define real as double, since the
 x87 is deprecated, and x64 ABI uses the SSE unit. It makes no sense at
 all to use real under any general circumstances in x64 builds.

 And aside from that, if you *think* you need real for precision, the
 truth is, you probably have bigger problems.
 Double already has massive precision. I find it's extremely rare to
 have precision problems even with float under most normal usage
 circumstances, assuming you are conscious of the relative magnitudes
 of your terms.
That's a common perception of people who do not use the floating point unit for numerical work, and whose main concern is speed instead of accuracy. I've done numerical floating point work. Two common cases where such precision matters: 1. numerical integration 2. inverting matrices It's amazing how quickly precision gets overwhelmed and you get garbage answers. For example, when inverting a matrix with doubles, the results are garbage for larger than 14*14 matrices or so. There are techniques for dealing with this, but they are complex and difficult to implement. Increasing the precision is the most straightforward way to deal with it. Note that the 80 bit precision comes from W.F. Kahan, and he's no fool when dealing with these issues. Another boring Boeing anecdote: calculators have around 10 digits of precision. A colleague of mine was doing a multi-step calculation, and rounded each step to 2 decimal points. I told him he needed to keep the full 10 digits. He ridiculed me - but his final answer was off by a factor of 2. He could not understand why, and I'd explain, but he could never get how his 2 places past the decimal point did not work. Do you think engineers like that will ever understand the problems with double precision, or have the remotest idea how to deal with them beyond increasing the precision? I don't.
 I find it's extremely rare to have precision problems even with float under 
most normal usage
 circumstances,
Then you aren't doing numerical work, because it happens right away.
Jun 27 2014
next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Saturday, 28 June 2014 at 05:16:29 UTC, Walter Bright wrote:
 That's a common perception of people who do not use the 
 floating point unit for numerical work, and whose main concern 
 is speed instead of accuracy.

 <snip>

 I find it's extremely rare to have precision problems even
with float under most normal usage
 circumstances,
Then you aren't doing numerical work, because it happens right away.
There is of course many situations where a high precision is necessary. But in these situations you have 'real' available to you, which presumably would maintain as high precision as is possible. In the situations where you're using float/double, you should not be expecting maximum precision and instead performance should be focused on. There are existing overloads for 'real' in std.math that presumably would not go away, the only need now is to add new overloads for float/double that can take advantage of SSE instructions. While striving for precision is nice, in a huge majority of situations it's simply not necessary (and when it is, 'real' will be used). It makes D look bad when it does so poorly on benchmarks like this simply so that the output perlin noise can be rounded from 238.32412319 to 238 instead of 238.32 to 238.
Jun 28 2014
prev sibling parent Manu via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 28 June 2014 15:16, Walter Bright via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On 6/27/2014 3:50 AM, Manu via Digitalmars-d wrote:
 Totally agree.
 Maintaining commitment to deprecated hardware which could be removed
 from the silicone at any time is a bit of a problem looking forwards.
 Regardless of the decision about whether overloads are created, at
 very least, I'd suggest x64 should define real as double, since the
 x87 is deprecated, and x64 ABI uses the SSE unit. It makes no sense at
 all to use real under any general circumstances in x64 builds.

 And aside from that, if you *think* you need real for precision, the
 truth is, you probably have bigger problems.
 Double already has massive precision. I find it's extremely rare to
 have precision problems even with float under most normal usage
 circumstances, assuming you are conscious of the relative magnitudes
 of your terms.
That's a common perception of people who do not use the floating point unit for numerical work, and whose main concern is speed instead of accuracy. I've done numerical floating point work. Two common cases where such precision matters: 1. numerical integration 2. inverting matrices It's amazing how quickly precision gets overwhelmed and you get garbage answers. For example, when inverting a matrix with doubles, the results are garbage for larger than 14*14 matrices or so. There are techniques for dealing with this, but they are complex and difficult to implement.
This is what I was alluding to wrt being aware of the relative magnitudes of terms in operations. You're right it can be a little complex, but it's usually just a case of rearranging the operations a bit, or worst case, a temporary renormalisation from time to time.
 Increasing the precision is the most straightforward way to deal with it.
Is a 14*14 matrix really any more common than a 16*16 matrix though? It just moves the goal post a bit. Numerical integration will always manage to find it's way into crazy big or crazy small numbers. It's all about relative magnitude with floats. 'real' is only good for about 4 more significant digits... I've often thought they went a bit overboard on exponent and skimped on mantissa. Surely most users would reach for a lib in these cases anyway, and they would be written by an expert. Either way, I don't think it's sensible to have a std api defy the arch ABI.
 Note that the 80 bit precision comes from W.F. Kahan, and he's no fool when
 dealing with these issues.
I never argued this. I'm just saying I can't see how defying the ABI in a std api could be seen as a good idea applied generally to all software.
 Another boring Boeing anecdote: calculators have around 10 digits of
 precision. A colleague of mine was doing a multi-step calculation, and
 rounded each step to 2 decimal points. I told him he needed to keep the full
 10 digits. He ridiculed me - but his final answer was off by a factor of 2.
 He could not understand why, and I'd explain, but he could never get how his
 2 places past the decimal point did not work.
Rounding down to 2 decimal points is rather different than rounding from 19 to 15 decimal points.
 Do you think engineers like that will ever understand the problems with
 double precision, or have the remotest idea how to deal with them beyond
 increasing the precision? I don't.
I think they would use a library. Either way, those jobs are so rare, I don't see that it's worth defying the arch ABI across the board for it. I think there should be a 'double' overload. The existing real overload would be chosen when people use the real type explicitly. Another advantage of this, is that when people are using the double type, the API will produce the same results on all architectures, including the ones that don't have 'real'.
 I find it's extremely rare to have precision problems even with float
 under most normal usage
 circumstances,
Then you aren't doing numerical work, because it happens right away.
My key skillset includes physics, lighting, rendering, animation. These are all highly numerical workloads. While I am comfortable with some acceptable level of precision loss for performance, I possibly have to worry about maintaining numerical precision even more since I use low-precision types exclusively. I understand the problem very well, probably better than most. More often than not, the problems are easily mitigated by rearranging operations such that operations are performed against terms with relative magnitudes, or in some instances, temporarily renormalising terms. I agree these aren't skills that most people have, but most people use libraries for complex numerical work... or would, if such a robust library existed. Thing is, *everybody* will use std.math.
Jun 29 2014
prev sibling next sibling parent Iain Buclaw via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 27 June 2014 07:48, Iain Buclaw <ibuclaw gdcproject.org> wrote:
 On 27 June 2014 07:14, Iain Buclaw <ibuclaw gdcproject.org> wrote:
 On 27 June 2014 02:31, David Nadlinger via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 Hi all,

 right now, the use of std.math over core.stdc.math can cause a huge
 performance problem in typical floating point graphics code. An instance of
 this has recently been discussed here in the "Perlin noise benchmark speed"
 thread [1], where even LDC, which already beat DMD by a factor of two,
 generated code more than twice as slow as that by Clang and GCC. Here, the
 use of floor() causes trouble. [2]

 Besides the somewhat slow pure D implementations in std.math, the biggest
 problem is the fact that std.math almost exclusively uses reals in its API.
 When working with single- or double-precision floating point numbers, this
 is not only more data to shuffle around than necessary, but on x86_64
 requires the caller to transfer the arguments from the SSE registers onto
 the x87 stack and then convert the result back again. Needless to say, this
 is a serious performance hazard. In fact, this accounts for an 1.9x slowdown
 in the above benchmark with LDC.

 Because of this, I propose to add float and double overloads (at the very
 least the double ones) for all of the commonly used functions in std.math.
 This is unlikely to break much code, but:
  a) Somebody could rely on the fact that the calls effectively widen the
 calculation to 80 bits on x86 when using type deduction.
  b) Additional overloads make e.g. "&floor" ambiguous without context, of
 course.

 What do you think?

 Cheers,
 David
This is the reason why floor is slow, it has an array copy operation. --- auto vu = *cast(ushort[real.sizeof/2]*)(&x); --- I didn't like it at the time I wrote, but at least it prevented the compiler (gdc) from removing all bit operations that followed. If there is an alternative to the above, then I'd imagine that would speed up floor by tenfold.
Can you test with this? https://github.com/D-Programming-Language/phobos/pull/2274 Float and Double implementations of floor/ceil are trivial and I can add later.
Added float/double implementations.
Jun 27 2014
prev sibling parent reply "Kagamin" <spam here.lot> writes:
I think, make real==double on x86-64, like on other 
architectures, because double is the way to go.
Jun 27 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/27/2014 11:47 AM, Kagamin wrote:
 I think, make real==double on x86-64, like on other architectures, because
 double is the way to go.
No. Consider also that on non-Windows platforms, such a decision would shut D out from accessing C code written using long doubles. BTW, there's a reason Fortran is still king for numerical work - that's because C compiler devs typically do not understand floating point math and provide crappy imprecise math functions. I had an argument with a physics computation prof a year back who was gobsmacked when I told him the FreeBSD 80 bit math functions were only accurate to 64 bits. He told me he didn't believe me, that C wouldn't make such mistakes. I suggested he test it and see for himself :-) They can and do. The history of C, including the C Standard, shows a lack of knowledge of how to do numerical math. For example, it was years and years before the Standard mentioned what the math functions should do with infinity arguments. Things have gotten better in recent years, but I'd always intended that D out of the gate have proper support for fp, including fully accurate math functions. The reason D re-implements the math functions in Phobos rather than deferring to the C ones is the unreliability of the C ones.
Jun 27 2014