Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP-UX Floating-Point Guide: HP 9000 Computers > Chapter 7 Performance Tuning

Denormalized Operands

» 

Technical documentation

Complete book in PDF
» Feedback
Content starts here

 » Table of Contents

 » Glossary

 » Index

Denormalized values usually occur as the result of an operation that underflows. On HP 9000 systems, the occurrence of a denormalized operand or result, either at an intermediate stage of a computation or at the end, can reduce the speed of an operation significantly. There are several solutions to this problem:

  • Change single-precision data to double-precision.

  • Assign the value zero to data that would normally be denormalized.

  • On systems that support it, enable flush-to-zero mode.

  • Scale the entire data set upwards in magnitude so that the smallest values that occur are guaranteed to be normalized.

The first solution applies primarily to code that uses single-precision data. Because of the range of the two formats, a value that is denormalized in single-precision will be normalized in double-precision. On HP 9000 systems, denormalized numbers are so costly that it is worth converting to double-precision even if this means converting several operands from single-precision to double-precision, performing several operations, and then converting the result back to single-precision. The code will still run much faster than it would if it had to process a single denormalized operand.

The second solution is useful only if you can determine that your algorithm will work equally well when a denormalized value is treated as zero. In this case, you can explicitly assign it the value 0 before entering a loop where it is repeatedly accessed. For example, if A is a denormalized operand in the following example, this code will run very slowly on a HP 9000 ­system:

      SUBROUTINE VECTOR_SCALE(A, V)
REAL A, V(1000)

PRINT *, 'A IS', A
DO 10 I = 1,1000
10 V(I) = V(I) * A
RETURN
END

If A is likely to be denormalized once in a while, it may be a good idea to add the following line before the loop:

      IF (ABS(A) .LT. 1.1754944E-38) A = 0.0

Of course, changing the denormalized value to zero can affect the accuracy of the algorithm. You need to determine whether this change will affect the usefulness of your program's output.

The third solution is to use flush-to-zero mode. If your target execution system supports flush-to-zero mode, you have the option of disabling gradual (that is, IEEE-754-compliant) underflow. To do so, use the +FPD compiler and linker option or the fesetflushtozero function. (The fesetflushtozero function always executes successfully. However, on system types that do not support fast underflow, the call has no effect.) These methods are described in Chapter 5 “Manipulating the Floating-Point Status Register”. Running the sample program in “Underflow Mode: fegetflushtozero and fesetflushtozero” will tell you whether your system supports fast underflow.

Using flush-to-zero mode can have the same effect on the accuracy of your algorithm as changing a value to zero, so use the same caution.

The final way to avoid denormalized numbers is to scale your entire algorithm upwards in magnitude. The exact way in which you do this depends on your algorithm because the results of most expressions do not scale up linearly as their operands are scaled. This method is more of a general way to rethink your overall algorithm than a way to fix the specific problem of denormalized values.

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1997 Hewlett-Packard Development Company, L.P.