[std-interval] Re: winter 2006 draft for standard C++ intervals
Lawrence.Crowl at sun.com
Lawrence.Crowl at sun.com
Sat Mar 4 00:01:16 PST 2006
Overall, I thought the proposal well written. I do have some
comments.
(A date would have helped in identifying the document, even if you do
not yet have a document number.)
============
Should std::valarray<interval> be allowed?
Note that Sun's interval library includes specializations for
valarray over intervals. This specialization improves performance
over the simple approach.
Should intervals be passed by value or by reference?
I strongly prefer the pass-by-value approach over the legacy
pass-by-reference approach of std::complex. The choice has
implications beyond the efficiency of the interval operations
because users will tend to copy the style of the standard. This
pass-by-reference style leads to inefficiency and incorrectness.
"Changing [interval parameters from pass-by-reference] to pass by
value would only penalize the other ABIs."
What evidence do you have to support this claim? In fact, for most
ABIs, the performance of intervals pass-by-value will be faster
than pass-by-reference. On those ABIs where performance by-value
is lower, it will be only marginally lower. (For example, on x86
pass-by-value pushes two words to the stack; pass-by-reference
varies from pushing one word to writing two words and pushing one.)
On the other hand, ABIs that support "small structs passed in
registers", the difference is signficant, often avoiding memory
entirely.
"Note that this point is moot when functions are inline, which is
expected to be the case most of the time."
This statement is entirely untrue for the simple implementations.
Pass-by-reference inhibits optimization. The problem is that
pass-by-reference introduces potential aliases between parameters.
The compiler must load/store intervals to memory at many
intermediate stages of computation to avoid incorrect results. In
contrast, value parameters cannot be aliased, and hence may be
retained in registers.
The aliasing problem is particularly severe because programmers
often write programs as though it did not exist. That is, they
write functions that fail when parameters are in fact aliased.
For example, the typical code for complex::operator*= is:
real = real*rhs.real - imag*rhs.imag;
imag = imag*rhs.real + real*rhs.imag;
and it fails under pass-by-reference for the expression c*=c.
Workarounds to this problem genrally involve retaining an extra copy
of something, which ends up being very similar to pass-by-value.
Now, imagine all that code where the programmer did not account for
aliasing in user-written functions. Now imagine all that code just
naturally corrected with pass-by-value.
This issue is very important.
26.6 Interval Numbers
Paragraph 2 has a stale reference to interval<bool>.
Paragraph 2 also says "instantiating the template interval for any
type other than ... is unspecified". By omitting the generic
template definition, and defining only the specializations, the user
cannot instantiate interval over any other type and the unspecified
behavior is gone. Is there any particular reason to provide the
generic template definition? If not, I suggest you remove it.
Section 26.6.2 would go away.
26.6.1 Header <interval> synopsis // values:
Several of the free functions seem more natural to me as member
functions. They are inf, sup, midpoint, and width.
26.6.1 Header <interval> synopsis // algebraic operators:
Why is square a "value", but sqrt is a "algebraic operator"?
26.6.1 Header <interval> synopsis // set operations:
These operations seem much more natural to me as member functions.
Consider:
if ( contains( a, b ) )
versus
if ( a.contains(b) )
or more signficiantly
a = intersect( hull( a, b ), c );
versus
a = a.hull(b).intersect(c);
As with the values functions, we need to balance the expectations of
the users. I speak of my expectations as a C++ expert, not of the
expectations of an interval expert. It may well be that changing
would be worse than not.
26.6.11 interval static value operations
Based on the example in VI.1, you also need
interval<T> interval<T>::epsilon()
{ return interval( -std::numeric_limits<T>::min(),
std::numeric_limits<T>::min() ); }
And based on the example in VI.2, you also need
interval<T> interval<T>::min()
{ return interval( std::numeric_limits<T>::min(),
std::numeric_limits<T>::min() ); }
which results in
assign_box( r, -std::interval<T>::min() );
============
Lawrence Crowl 650-786-6146 Sun Microsystems, Inc.
Lawrence.Crowl at Sun.com 16 Network Circle, UMPK16-303
http://www.Crowl.org/Lawrence/ Menlo Park, California, 94025
More information about the Std-interval
mailing list