5 ms·
This essay raises a lot of concerns about global state, especially with regard to rounding and flags (or exceptions). That's a common misconception, but nothin
by stephencanon 12y ago
This essay raises a lot of concerns about global state, especially with regard to rounding and flags (or exceptions). That's a common misconception, but nothing in IEEE-754 requires that this state be global. In the C language bindings, for example, dynamic rounding mode and status flags have thread scope.
In fact, dynamic rounding modes are not required at all by IEEE-754 (2008). The revised standard requires that languages provide a means to specify static rounding at "block" scope, which is a language-defined syntactic unit.
> (4.1) the implementation shall provide language-defined means, such as compiler directives, to specify a constant value for the attribute parameter for all standard operations in a block; the scope of the attribute value is the block with which it is associated.
> (2.1.7) block: A language-defined syntactic unit for which a user can specify attributes.
You can take "block" to mean whatever makes sense for your language: it could be a single arithmetic operation[1] or it could be the whole program (though it's more useful if it isn't). It is recommended, but not required, that languages provide a means to access "dynamic" rounding modes as well, which correspond roughly to what most people think of when they think of IEEE-754 rounding modes as widely implemented, but again a huge amount of flexibility is left to the languages to choose exactly what scope and precedence rules make sense for their language.
[1] efficient hardware support for such fine-grained static rounding is still somewhat lacking in the commodity CPU world. On GPUs and some other compute devices, it is quite natural (and "dynamic" rounding is sometimes quite a hassle). AVX-512 will bring support for per-instruction static rounding to mainstream CPUs.
When we look at flags, the situation is much the same. Languages completely specify the scope of flags. There is no requirement of mutable global state. For example:
> (7.1) Language standards should specify defaults in the absence of any explicit user specification, governing ... whether flags raised in invoked functions raise flags in invoking functions.
Like with rounding, current commodity CPUs make it easier to provide flags with thread scope, but IEEE-754 does not require it. Commodity hardware works the way it does because mainstream languages work that way. If a different model makes sense for your language, do that.
Finally, the concern about "exceptions" is entirely misplaced. "Exception" in IEEE-754 simply means "an event that occurs when an operation on some particular operands has no outcome suitable for every reasonable application," which is a rather different meaning than the way "exception" is understood in colloquial PL usage. Under default exception handling, which is all that IEEE-754 requires implementations to support, all that needs to happen in the case of an exception is for the implementation to raise the corresponding flag, the scope of which is (as previously discussed) up to the language to specify.
I would encourage you to direct questions like these about the spec to committee members. If you work for a big company, a few members probably work with you. If you don't, most committee members are happy to answer questions, even from people they don't know.
The concerns about access to the spec itself and to the minutes are well-placed, and definitely something that the committee is aware of. (But mostly out of the committee's hands; it's up to IEEE to set pricing. Send them your comments!)
- plesner 12y ago> nothing in IEEE-754 requires that this state be global. In the C language bindings, for example, dynamic rounding mode and status flags have thread scope. My example, RegExp captures in JavaScript, also have thread scope. Thread local global state is still not good. What makes the flags global is that access to them is provided implicitly and ubiquitously, independent of scope. All the operations as well as the flag functions like saveAllFlags are given read and/or write access and none of them take arguments that control the scope of the flags they're manipulating. They get pulled from thin air. This is problematic. I deliberately never say that the rounding flags are global, my strawmen are that they're either lexically or dynamically scoped, both of which are problematic. > You can take "block" to mean whatever makes sense for your language: it could be a single arithmetic operation[1] or it could be the whole program (though it's more useful if it isn't). What I'm arguing is that there is no interpretation of "block" that yields a satisfying result. I didn't consider applying it to individual operations because the whole motivation for the rounding mode mechanism is to keep the same mode is in effect across multiple operations. The lack of hardware support suggests the same thing. Maybe you can give an example of how you see this working where the attributes are more tightly scoped than per-thread? > Finally, the concern about "exceptions" is entirely misplaced. "Exception" in IEEE-754 simply means "an event that occurs when an operation on some particular operands has no outcome suitable for every reasonable application," which is a rather different meaning than the way "exception" is understood in colloquial PL usage. Fair enough, though that introduces a new problem: how do you implement fp-exceptions if the're not language level exceptions? But maybe if a reasonable solution can be found for the rounding flags something like that would work for the exceptions too. > I would encourage you to direct questions like these about the spec to committee members. If you work for a big company, a few members probably work with you. If you don't, most committee members are happy to answer questions, even from people they don't know. I did, I raised some of these issues, including the licensing issue, with David Bindel a year ago.
- Sanddancer 12y agoFor floating point exceptions, I'd say go with a mechanism like C's fenv.h [1]. It's out of the way, and handles rounding flags too. For if you're passing attributes around in different threads, my first thought would be (ab)using a language's type/object system to make sure that all your threads are using the same assumptions for floating point behavior; something like classes named FloatUp, FloatDown, FloatZero, FloatClose. http://pubs.opengroup.org/onlinepubs/009695399/basedefs/fenv.h.html http://pubs.opengroup.org/onlinepubs/009695399/basedefs/fenv...