Topic: Maths library (was: why C/C++ have no reentrant functions ?)
Author: "Ross Smith" <ross.s@ihug.co.nz>
Date: 1998/09/12 Raw View
Besides the overhead of argument checking and exception throwing,
another reason why the C and C++ standards have been intentionally vague
about error handling in FP functions is instruction pipelining. Modern
CPUs don't do everything synchronously; instructions may be rearranged
and parallelised for maximum efficiency. An FP hardware exception may
happen somewhere other than the point that a naive reading of the
high-level source code would expect.
It's possible to get around this by having the compiler insert explicit
FP synchronisation instructions at strategic places. This is a Bad
Thing. In FP-intensive programs, it can slow things down by an order of
magnitude. Presumably, FP-intensive code is exactly where our
hypothetical updated maths library is intended to help the most.
My suggestions...
First, have the new library (I'll call it "namespace maths", in a
probably doomed attempt to avoid setting another Americanism in stone)
rely on hardware exceptions rather than explicit insertion of argument
checking, to the extent possible on the target platform.
Now, we add a new function, void maths::sync(). This (conceptually)
inserts an explicit FP synchronisation. FP exceptions (hardware
exceptions translated into C++ exceptions) are *not* guaranteed to
happen at exactly the point of call of the function that fails -- only
somwhere between that call and the next call to sync(). For example:
double x(-1.0);
double y(maths::sqrt(x)); // <-- Point A
// more code goes here
maths::sync(); // <-- Point B
This will throw a domain error, but not necessarily at point A; it's
only guaranteed to be thrown somewhere between points A and B.
To give the optimiser, and the CPU's internal scheduler, freedom to
rearrange code for maximum efficiency, if multiple FP exceptions may be
thrown between two synchronisation points, no promises are made about
which one will actually escape. For example:
double a(-1.0), b(0.0);
double c(maths::sqrt(a));
double d(a / b);
maths::sync();
This will throw either a domain error or a divide-by-zero error, but it
is unspecified which one.
--
Ross Smith ................................... mailto:ross.s@ihug.co.nz
.............. The Internet Group, Auckland, New Zealand ..............
"Remember when we told you there was no future? Well, this is it."
-- Blank Reg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]