[Cfp-interest 2561] Fwd: Floating point environment

Jim Thomas jaswthomas at sbcglobal.net
Tue Nov 15 08:58:20 PST 2022


Hans Boehm from the C++ committee contacted me about the idea of rounding direction specific functions. I’m forwarding our email thread (best start at the bottom), and have added the topic to our agenda for the CFP meeting this Wednesday (Nov 16).

- Jim Thomas

> Begin forwarded message:
> 
> From: Hans Boehm <boehm at acm.org>
> Subject: Re: Floating point environment
> Date: November 14, 2022 at 1:37:30 PM PST
> To: Jim Thomas <jaswthomas at sbcglobal.net>
> 
> Actually, looking more closely, I do see in the C++ standard (wg21.link/n4917):
> 
> [Note 1 : This document does not require an implementation to support the FENV_ACCESS pragma; it is implementation defined (15.9)
> whether the pragma is supported. As a consequence, it is implementation-defined whether these
> functions can be used to test floating-point status flags, set floating-point control modes, or run under non-default
> mode settings. If the pragma is used to enable control over the floating-point environment, this document does not
> specify the effect on floating-point evaluation in constant expressions. — end note]
> 
> FENV_ACCESS is not mentioned in the synopsis for fenv.h.
> 
> I actually don't fully understand the history here, though I may have inadvertently played a role in it, since I was somewhat
> involved in rebasing the C++ standard onto C11. C++ may have gotten FENV_ACCESS kind of by accident, and the note
> may have been an attempt to extract ourselves from some sticky issues.
> 
> C exempts compile-time evaluations from fenv rounding, even with FENV_ACCESS on? I think that's also common for
> C++ implementations, which can make it quite hard to tell what's included and what's not.
> 
> On Mon, Nov 14, 2022 at 9:28 AM Jim Thomas <jaswthomas at sbcglobal.net <mailto:jaswthomas at sbcglobal.net>> wrote:
>> 
>> 
>>> On Nov 12, 2022, at 7:26 PM, Hans Boehm <boehm at acm.org <mailto:boehm at acm.org>> wrote:
>>> 
>>> 
>>> 
>>> On Fri, Nov 11, 2022, 7:45 AM Jim Thomas <jaswthomas at sbcglobal.net <mailto:jaswthomas at sbcglobal.net>> wrote:
>>>> 
>>>> 
>>>>> On Nov 9, 2022, at 12:11 AM, Hans Boehm <boehm at acm.org <mailto:boehm at acm.org>> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>> On Tue, Nov 8, 2022 at 12:25 PM Jim Thomas <jaswthomas at sbcglobal.net <mailto:jaswthomas at sbcglobal.net>> wrote:
>>>>>> Hi Hans,
>>>>>> 
>>>>>> A few off the cuff responses …
>>>>> Thanks! 
>>>>>> 
>>>>>> I don’t know about the issues with constexpr and dynamic rounding mode control, so can’t comment about that.
>>>>> The real problem seems to be that common implementations tend to ignore rounding modes, at least sometimes, when evaluating constants at compile time. 
>>>> 
>>>> Putting the code under an FENV_ACCESS pragma is intended (required by C) to prohibit that. Yes, unfaithful compilers undermine potentially helpful features.
>>> 
>>> Yes. But I think it's also not even mentioned in the C++ standard. And I suspect the required implementation effort is greater than the perceived utility.
>> 
>> The FENV_ACCESS pragma comes with including the C fenv.h header. Does C++ explicitly exclude the pragma or the header? 
>> 
>> The pragma can be very useful. Where its state is “on” (it’s “off” by default) the user can assume compiler optimizations won’t undermine use of the floating-point environment (flags and modes) and only there must the compiler refrain from applying those optimizations. This is important because otherwise desirable optimizations commonly “break” access to the floating-point environment. 
>> 
>> Compilers in my experience had an option for strict semantics. A minimal implementation of FENV_ACCESS might be just applying that option locally.
>> 
>>>>>> 
>>>>>> The revision committee for IEEE 754-2008 understood that dynamic rounding was problematic for important computational models. The committee introduced static rounding attributes, made them a requirement, and relegated dynamic rounding modes to a recommended feature. IEEE 754-2008 did not deprecate or remove dynamic rounding modes, nor did 754-2019.
>>>>> 
>>>>> But presumably the language binding is not specified?  So a template parameter along the lines of (ancient) http://wg21.link/n2811 would work as well?
>>>> 
>>>> IEEE 754 requires an “attribute” to control the rounding direction and says, "An attribute is logically associated with a program block to modify its numerical and exception semantics.” It defines a “block” as, "A language-defined syntactic unit for which a user can specify attributes. Language standards might provide means for users to specify attributes for blocks of varying scopes, even as large as an entire program and as small as a single operation.” I don’t think the intention was for languages to provide only entire program or single operation scopes.
>>>> 
>>>> Given C’s block scoped pragmas, it is straightforward and simple to write wrappers to provide operations that use a specific rounding direction. But using rounding mode specific functions to get the effect of the pragmas is a bigger job that must be repeated everyplace the block scoping is needed. 
>>>> 
>>>>>> 
>>>>>> 
>>>>>> Dynamic rounding modes can be helpful in deciding if round-off errors are substantially affecting results. When the code is run under different rounding modes, the variation in the results is usually a good indication. The alternative of error analysis is often not feasible.
>>>>> That's an interesting use I hadn't thought of. How widely used is that? It seems very hacky and brittle. Though I can believe that it often works for carefully written code that doesn't use any rounding mode control for internal purposes. Would a compiler flag be more appropriate here? Especially for C++ where constructors and destructors would otherwise be hard to include?
>>>>>> 
>>>>>> I suspect there’s a significant amount of C code that still uses dynamic rounding modes.
>>>>>> 
>>>>>> Consideration of dynamic vs static rounding control is affected by the underlying hardware. Static rounding control might be very inefficient if the hardware supports only dynamic modes. (And vice versa.)
>>>>> For other uses of rounding modes, if the intent is to upper- or lower-bound the mathematical result, it seems to me that you probably would not use the same rounding mode for more than a very small number of operations in a row anyway, e.g. to upper bound a - (b+c), you would want to round the addition towards -infinity and the subtraction towards +infinity. So frequent mode changes seem inevitable. So does it really matter?
>>>> 
>>>> Certainly the user must be aware of sign changes when rounding toward +/- infinity. Some computations, e.g. sums of positive terms (squares or absolute values), do not need intermediate rounding mode changes. And some computations do.
>>>>>> 
>>>>>> You might take your question about deprecating dynamic rounding to stds-754 at listserv.ieee.org <mailto:stds-754 at listserv.ieee.org>. IEEE 754-2019 is still fresh and the next revision hasn't started up yet, but some people still respond to questions. You might get some individual opinions now and get it on the list of issues for the next revisions.
>>>>> Good idea. Thanks! 
>>>> 
>>>> Also, I’ll add this to the agenda for the next CFP meeting, provided it’s ok with you for me to share parts of this thread with the group.
>>> 
>>> Please do!
>>>> 
>>>>>> 
>>>>>> The CFP group generally stays behind IEEE 754. Our purpose is to propose C support for that standard.
>>>>> I wonder whether this is a bit backwards. The arithmetic standard should clearly specify how operations are rounded. But how the rounding mode is specified seems more like a PL issue to me. IEEE 754 biased this towards a per-code-region rather than a per-operation specification, and there may be instruction encoding issues for that at the hardware level.
>>>> 
>>>> One of the goals of IEEE 754-2008 was to give more guidance to language standards, because no matter how well the rounding is specified uncareful compilers can make numerical codes hard to write and unreliable. As you note, IEEE 754 does not specify language binding. It tried to specify features that were feasible for major languages.
>>>> 
>>>> What are the hardware issues that make block specification more difficult than instruction specification? I would think it would be a not particularly difficult job for the compiler. What the compiler has to do depends on the hardware. Is that your point?
>>> 
>>> I would think that function-level specification basically involves no compiler work, for a minimal correct, though suboptimal, implementation. For modern compilers, it's generally a bunch of inline functions with asm bodies. That seems like a good thing, given that many implementers seem to view this as having marginal utility. (This assumes no constexpr support is required for C++, which I think is OK. It would also make constexpr support feasible with a bit of compiler work.)
>>> 
>>> But I think the main advantage is usability. If I write sin(x, some_rounding_mode), I either get the right answer, or a compiler error that that function doesn't exist. Similarly, user-defined functions either implement explicit rounding modes or not. I get no runtime surprises. Granted, the C standard does specify which function behave which way, but having to consult the standard for this every time is unfortunate.
>>> 
>>> I also think that if you're trying to bound the true result, you really have to think about every operation. Doing this on a block basis is an impedance mismatch with programmer thought processes. It doesn't make sense to say that every operation in sin(x+y) should be rounded up.
>>> 
>>> Granted, there are cases in which it happens to do the right thing. But otherwise innocuous changes to an inner subexpression can clearly break that.
>>> 
>>> Hans
>>> 
>>>> 
>>>> - Jim
>>>> 
>>>>>> 
>>>>>> Library functions with an extra rounding direction argument would have to cover the relevant built-in operators and math, stdlib, and stdio functions and tgmath macros. How would it handle conversions? The number of identifiers for numerical functionality is already an issue for namespace-less C.
>>>>> Conversions would have to be explicit. But again, for anything that cares about provable properties of the results, it's not clear to me that you actually want implicit conversions with the current mode under the covers. That may be a feature rather than a bug.
>>>>> 
>>>>> As far as naming is concerned, we could use atomics like naming in C, with an sin_explicit(x, rounding_mode), etc. That's probably a bad suffix choice. But in any case, it should be possible to get by with 2 names per function. In C++, this isn't an issue.
>>>>> 
>>>>> Hans
>>>>>> 
>>>>>> - Jim
>>>>>> 
>>>>>> 
>>>>>> > On Nov 7, 2022, at 10:42 PM, Hans Boehm <boehm at acm.org <mailto:boehm at acm.org>> wrote:
>>>>>> > 
>>>>>> > Hi, Jim,
>>>>>> > 
>>>>>> > I have a technical question for you:
>>>>>> > 
>>>>>> > The C++ committee seems to keep running into issues, mostly related to C++ constexpr, with fenv-based dynamic rounding mode control. Some of us have arrived at the conclusion that, at least in C++, this is a facility that creates many problems, mostly related to constant expression evaluation, and is basically unusable anyway.
>>>>>> > 
>>>>>> > I know of very few use cases, and those generally have to control rounding on a per operation basis, not in a dynamic, or even static, scope. Given the choice, the new C statically-scoped #pragma stuff is better, but it still seems to be less useful than a simple library of operations that take rounding mode arguments.
>>>>>> > 
>>>>>> > Is that also your thinking? Or are there technical arguments for the status quo that we're overlooking? I'm tempted to try to deprecate dynamic rounding mode control in C++. Is that a non-starter in C?
>>>>>> > 
>>>>>> > Hans
>> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20221115/692931c0/attachment-0001.htm>


More information about the Cfp-interest mailing list