[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
reproducibility of tininess detection for binary formats
- To: stds-754 <stds-754@xxxxxxxxxxxxxxxxx>
- Subject: reproducibility of tininess detection for binary formats
- From: Michel Hack (1-914-784-7648) <hack@xxxxxxxxxxxxxx>
- Date: Sunday 14 Oct 2007 at 10:49 p.m. EDT (2007-10-15 02:49 GMT)
turning off extra signals with a trap that occurs only on
signals is bound to be more efficient than testing every
unexceptional operation to see if it should have signaled.
Only if (a) the trap is restartable, and (b) the trap has no
side-effects that would be visible, but cannot be undone.
As I explained earlier, on the two architectures that I know
well, this is possible on one but not on the other.
I don't think any language standards committees are likely to
develop a consensus that it's a worthwhile option to pursue.
Then why are we bothering with Clause 11? Ok, so perhaps the
mainstream languages won't pick it up -- but any language that
does pick it will have to tolerate the consequences, and I think
we should try to keep those under control -- if we bother at all.
Reproducible mode could leave out tininess standardisation. That
was indeed my first reaction. In that case, programs will be on
their own, and the question is, what other assistance would they
need? Clearly, one of them is the ability to determine whether
any remediation is needed at all, i.e. a whichTiny() predicate.
If I had to write a reproducible program that cares about underflow
(otherwise the issue is moot, as results other than exception flags
are already reproducible), I might decide based on which platform
I expect to run most, and provide remediation for other platforms
regardless of cost. If I don't want excessive cost on any platform,
I would however choose to use tininess-before-rounding. I would
write macros for cast(), div() and mult(), and use those instead
of the primitives. I am assuming that all other reproducibility
issues are under control.
Here is my mult() macro, in pseudo-C for readability, for a static
rounding environment. The compiler is expected to do constant
propagation and dead code elimination, so the macro will often
expand to very little code. Ideally the compiler should also support
outlining -- the opposite of inlining, where a common sequence of
operations is compiled into a private subroutine with minimal linkage.
(Remember that I'm an assembly-language programmer, and that's what I
do when I play compiler and write large programs.)
#define mult(x,y)
if (whichTiny() == TINY_BEFORE) x * y;
else { double ta,tb;
ta = x * y;
switch (getBinaryRoundingDirection()) {
case roundTowardZero: break;
case roundTowardPositive: if (ta != DOUBLE_NMIN) break;
setBinaryRoundingDirection(roundTowardZero);
tb = x * y;
setBinaryRoundingDirection(roundTowardPositive);
if (ta==tb) break;
signalException(Underflow); break;
case roundTowardNegative: if (ta != -DOUBLE_NMIN) break;
setBinaryRoundingDirection(roundTowardZero);
tb = x * y;
setBinaryRoundingDirection(roundTowardNegative);
if (ta==tb) break;
signalException(Underflow); break;
case roundTiesToEven: if ((ta != +DOUBLE_NMIN) &&
(ta != -DOUBLE_NMIN) ) break;
setBinaryRoundingDirection(roundTowardZero);
tb = x * y;
setBinaryRoundingDirection(roundTiesToEven);
if (ta==tb) break;
signalException(Underflow); break;
}
ta;
}
If the modes are really static, the switch statement should disappear.
Note that I don't have to mess with the flags -- unlike what would be
required if I had to undo an exception.
This is still very messy to program, however. I need a macro for each
arithmetic type that I use; I would refrain from using mixed types. If
roundTiestoAway is supported, I would not be using it, as this would
not be portable -- so omitting it in my macro should be ok.
However, an advantage of having the programmer deal with this explicitly
is that cases where underflow is not an issue may be known, and those
need not use the defensive macros.
Michel.
Sent: 2007-10-15 04:20:49 UTC