View mode: basic / threaded / horizontal-split · Log in · Help
September 11, 2009
Re: Floating point rounding modes: we should restrict them slightly
Don wrote:
> PROPOSAL:
> Change the spec by adding the line to float.html:
> "If the floating-point rounding mode is changed within a function, it 
> must be restored before the function exits. If this rule is violated 
> (for example, by the use of inline asm), the rounding mode used for 
> subsequent calculations is undefined."

But that doesn't allow for changing the rounding mode at a global level, 
then rerunning one's computation to determine how rounding affects their 
final result.
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
Walter Bright wrote:
> Don wrote:
>> PROPOSAL:
>> Change the spec by adding the line to float.html:
>> "If the floating-point rounding mode is changed within a function, it 
>> must be restored before the function exits. If this rule is violated 
>> (for example, by the use of inline asm), the rounding mode used for 
>> subsequent calculations is undefined."
> 
> But that doesn't allow for changing the rounding mode at a global level, 
> then rerunning one's computation to determine how rounding affects their 
> final result.

It doesn't prevent that at all. You just need to change the rounding 
mode before running your computation (at the start of main(), for 
example), and then reset it after performing the computation. What it 
does do is prevent different terms within a single expression from 
interacting which other.

eg
double foo() {
  return x() + y();
}
x() and y() can use whichever rounding modes they like, and if they are 
impure, they can affect one another, but under this proposal, they 
cannot change the meaning of the addition inside foo().
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
Stewart Gordon wrote:
> Don wrote:
> <snip>
>> LISTING ONE:
>>
>> real x = foo(1) + foo(2) + foo(3);
>>
>> LISTING TWO:
>>
>> real x1 = foo(1);
>> real x2 = foo(2);
>> real x3 = foo(3);
>> real x = x1 + x2 + x3;
>>
>> In C and C++ (and currently in D), they are NOT equivalent!
>> foo() is allowed to change the floating-point rounding mode, so it 
>> could change the meaning of '+'.
> <snip>
> 
> This is just one aspect of it.  You could also call a pure function, 
> change the rounding mode, and then call the pure function again on the 
> same arguments.  The value returned would change, thereby violating the 
> purity.

I already presented a proposal for that. This proposal is primarily for 
functions which are not pure.

> There has been some talk about pure functions in relation to locales:
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=3057
> http://www.digitalmars.com/d/archives/digitalmars/D/std.locale_85081.html
> 
> Floating point settings are just another case of the same thing, except 
> that currently violations in relation to the former are allowed.

There's a fundamental difference between them: the floating point 
settings are a hardware feature and it is IMPOSSIBLE to avoid them. You 
can choose not to use locale settings. Or, you can pass them as a 
parameter, which doesn't work for floating point settings.

Please do not get sidetracked on pure functions, it is orthogonal to 
this issue.
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
On 2009-09-13 06:14:02 -0400, Don <nospam@nospam.com> said:

> double foo() {
>    return x() + y();
> }
> x() and y() can use whichever rounding modes they like, and if they are 
> impure, they can affect one another, but under this proposal, they 
> cannot change the meaning of the addition inside foo().

Problems still may occur if x and y do memoization however. You call 
x() with one rounding mode, it memoize the results, then call x() with 
another rounding mode and it reuses the previous results while it 
shouldn't.

Basicaly, any memoization of x() should be discarded when you change 
the rounding mode. For instance the compiler should not reuse the value 
of x(), even if x is pure, in the following code:

	auto a = x();
	setRoundingMode(...);
	auto b = x();

Basically, setRoundingMode should act as some sort of barrier for the 
optimizer, but how?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
Michel Fortin wrote:
> On 2009-09-13 06:14:02 -0400, Don <nospam@nospam.com> said:
> 
>> double foo() {
>>    return x() + y();
>> }
>> x() and y() can use whichever rounding modes they like, and if they 
>> are impure, they can affect one another, but under this proposal, they 
>> cannot change the meaning of the addition inside foo().
> 
> Problems still may occur if x and y do memoization however. 

Yes, but this is an orthogonal issue, which I have discussed previously.

> Basicaly, any memoization of x() should be discarded when you change the 
> rounding mode.

> Basically, setRoundingMode should act as some sort of barrier for the 
> optimizer, but how?

It's not a big deal, because rounding mode is changed so rarely, so you 
don't need to exactly catch all the cases where memoisation can safely 
be used; you only need to disallow all of the ones where it is unsafe.

I proposed two options: (1) by analogy to SafeD, allow rounding mode and 
float exception flags to be respected only in specially marked modules 
('module(advancedfloatingpoint)' or similar). Memoisation should be 
disabled in such modules. (As a further optimisation, the compiler can 
re-enable memoisation when such functions are called from 
non-advancedfloatingpoint modules).
(2) provide a runtime call to disable memoisation. You'd be obliged to 
call this every time you changed the rounding mode or exception status 
from the default.

I favour (1) because it provides huge optimisation potential for modules 
with default floating point.

The point of all my proposals on this topic, is that these features 
cause a lot of trouble if they're completely unrestrained in the way 
that C/C++ does it, but the semantics required to completely domesticate 
them are not burdensome, and can be done without loss of useful 
functionality.
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
Walter Bright wrote:
> Don wrote:
>> PROPOSAL:
>> Change the spec by adding the line to float.html:
>> "If the floating-point rounding mode is changed within a function, it 
>> must be restored before the function exits. If this rule is violated 
>> (for example, by the use of inline asm), the rounding mode used for 
>> subsequent calculations is undefined."
> 
> But that doesn't allow for changing the rounding mode at a global level, 
> then rerunning one's computation to determine how rounding affects their 
> final result.

Ok, I understand now. This makes sense.
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
Don wrote:
> PROPOSAL:
> Change the spec by adding the line to float.html:
> "If the floating-point rounding mode is changed within a function, it 
> must be restored before the function exits. If this rule is violated 
> (for example, by the use of inline asm), the rounding mode used for 
> subsequent calculations is undefined."


I added it into float.html for D2.
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
Don wrote:
<snip>
>> Floating point settings are just another case of the same thing, 
>> except that currently violations in relation to the former are allowed.
> 
> There's a fundamental difference between them: the floating point 
> settings are a hardware feature and it is IMPOSSIBLE to avoid them.

Actually, you _can_ avoid changing the floating point settings in the 
course of an average program.  But still....

> You can choose not to use locale settings. Or, you can pass them as a 
> parameter, which doesn't work for floating point settings.

As long as it's the built-in arithmetic operators you're concerned 
about.  But that said, wrapping every arithmetic operation in a function 
to purify it of dependence on floating point settings wouldn't be ideal.

> Please do not get sidetracked on pure functions, it is orthogonal to 
> this issue.

I'm not sure about this.  ISTM arithmetic operators are essentially pure 
functions, and so the compiler may treat them as such.

Stewart.
September 13, 2009
Re: Floating point rounding modes: we should restrict them slightly
Walter Bright:

> Don:
> > PROPOSAL:
> > Change the spec by adding the line to float.html:
> > "If the floating-point rounding mode is changed within a function, it 
> > must be restored before the function exits. If this rule is violated 
> > (for example, by the use of inline asm), the rounding mode used for 
> > subsequent calculations is undefined."
> 
> I added it into float.html for D2.

An important purpose of a not bug-prone language is remove as many undefined situations as possible. If you add that to D2 specs, can the compiler catch at compile time all cases of violations to that rule?

D has something for the actions that must be done before the function exits, the scope(exit). Can something like that be used to automatically avoid undefined rounding situations?

Bye,
bearophile
September 14, 2009
Re: Floating point rounding modes: we should restrict them slightly
bearophile wrote:
> An important purpose of a not bug-prone language is remove as many
> undefined situations as possible.

That's right.

> If you add that to D2 specs, can
> the compiler catch at compile time all cases of violations to that
> rule?

Unlikely. But that has to be weighed against the former behavior being 
defined in a useless way.


> D has something for the actions that must be done before the function
> exits, the scope(exit). Can something like that be used to
> automatically avoid undefined rounding situations?

Using an RAII object to do it might be better.
1 2 3 4
Top | Discussion index | About this forum | D home