home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / documents / audio / audio.apps / dev / fp.underflow next >
Encoding:
Text File  |  1996-11-11  |  8.4 KB  |  200 lines

  1. [Chris Pirazzi provides the following useful information (thanks,
  2. Chris!) -Doug]
  3.  
  4. From cpirazzi@cp.esd.sgi.com  Mon Jul 24 22:57:19 1995
  5. Received: from cp.esd.sgi.com by candiru.engr.sgi.com via ESMTP (940816.SGI.8.6.9/911001.SGI)
  6.     for <cook@candiru.engr.sgi.com> id WAA26935; Mon, 24 Jul 1995 22:57:19 -0700
  7. Received: by cp.esd.sgi.com (940816.SGI.8.6.9/940406.SGI.AUTO)
  8.     for cook id WAA05094; Mon, 24 Jul 1995 22:57:18 -0700
  9. Date: Mon, 24 Jul 1995 22:57:18 -0700
  10. From: cpirazzi@cp.esd.sgi.com (Chris Pirazzi)
  11. Message-Id: <199507250557.WAA05094@cp.esd.sgi.com>
  12. To: cook@cp.esd.sgi.com
  13. Subject: floating point underflow exceptions
  14. Status: OR
  15.  
  16.  
  17. you might want to include some info from here on
  18. your signal processing faq.
  19.  
  20. this has saved me several times.
  21.  
  22. this is the final version of my faq item
  23.  
  24. ============================================================================
  25.  
  26.  
  27. well, it has taken me several months, but I have finally tracked down
  28. all the bugs and needed details concerning floating point underflow
  29. exception handling.
  30.  
  31. this information should help people to identify a condition that could
  32. speed up their signal processing code by hundreds of times.
  33.  
  34. ------------------------------
  35.  
  36. FAQ item for comp.sys.sgi.misc and comp.sys.sgi.audio FAQ's
  37.  
  38. (I guess it should probably be in .misc, and there should be a pointer
  39.  question in .audio.  It is definitely NOT just an audio thing, but
  40.  audio people really want to know this.)
  41.  
  42. ------------------------------
  43.  
  44. Subject:   -XX-  why does my floating point signal processing routine, 
  45.                  when given certain inputs, run incredibly slowly and 
  46.                  consume all of the CPU in _system_ or _interrupt_ time ?
  47. Date: Mon Jul 24 22:28:13 PDT 1995
  48.  
  49. You may be experiencing an undesirable "floating point underflow"
  50. behavior of the floating point unit on R3k's and beyond.  Roughly, a
  51. floating point underflow (defined in IEEE standard 754) occurs when a
  52. floating point operation creates a non-zero number whose absolute
  53. value is so small that it would cause other exceptions in subsequent
  54. operations.  When an underflow occurs that is not somehow masked, the
  55. FPU causes an interrupt (R3k) or trap (R4k and later) on the CPU, the
  56. CPU runs some code to handle the trap, and then the floating point
  57. instruction in your program completes.  This happens once for each
  58. underflowing instruction.
  59.  
  60. Recursive filters will often generate large numbers of underflows in
  61. large spans, and so they often clearly reveal the slow processing of
  62. these exceptions.  Code can easily run hundreds or thousands of times
  63. more slowly if it underflows on every operation.
  64.  
  65. - How Do I Tell if I'm Getting Lots of Floating Point Underflows?
  66.  
  67. On R3k machines, programs that are performing lots of operations which
  68. underflow will eat up the CPU in "intr" time (the yellow part of the
  69. CPU bar on gr_osview).
  70.  
  71. On R4k and later machines, such programs will eat up the CPU in
  72. "system" time (the red part of the CPU bar on gr_osview), since trap
  73. handling counts towards "system" time.
  74.  
  75. You can check for these underflows (and other exceptions) more
  76. reliably by temporarily linking your program with -lfpe, setting the
  77. environment variable TRAP_FPE to 'DEBUG;ALL=COUNT(1)', and running
  78. your program.  This will print something every time any floating point
  79. exception occurs.  You probably want to change the 1 to some large
  80. number so that you can see just how many FPE's occur without waiting
  81. for thousands of printfs.
  82.  
  83. - How Do I Fix It?
  84.  
  85. There are two methods:
  86.  
  87. 1. Link your program with -lfpe, and execute the following code
  88. snippet in your program once, before your signal processing code:
  89.  
  90. #include <sigfpe.h>
  91.  
  92.   /* 
  93.      set underflowing values to zero (_ZERO), but in particular,
  94.      also set the special "flush zero" bit (FS, bit 24) in the 
  95.      Control Status register.  This bit exists in R4k and later
  96.      processors.  This special bit will cause the FPU not to
  97.      generate an exception for floating point underflows, and
  98.      quietly substitute zero instead.  On R3k CPUs, this
  99.      setting will be treated just like "_ZERO."
  100.   */    
  101.   sigfpe_[_UNDERFL].repls = _FLUSH_ZERO;
  102.   handle_sigfpes(_ON, _EN_UNDERFL, NULL, 
  103.                  _ABORT_ON_ERROR, NULL);
  104.  
  105.  
  106. 2. (works on R4000 and later processors ONLY) execute the following
  107. code snippet in your program once, before your signal processing code
  108. (linking with libfpe is neither required nor recommended for method
  109. 2):
  110.  
  111. #include <sys/fpu.h>
  112.  
  113.   /*
  114.     set the special "flush zero" but (FS, bit 24) in the
  115.     Control Status Register of the FPU of R4k and beyond
  116.     so that the result of any underflowing operation will
  117.     be clamped to zero, and no exception of any kind will
  118.     be generated on the CPU.  This has no effect on 
  119.     an R3000.
  120.   */
  121.   void flush_all_underflows_to_zero()
  122.   {
  123.     union fpc_csr f;
  124.     f.fc_word = get_fpc_csr();
  125.     f.fc_struct.flush = 1;
  126.     set_fpc_csr(f.fc_word);
  127.   }
  128.  
  129. Method 2 is highly recommended and preferred for development of any
  130. code that does not need to execute on R3000 CPUs.  See below for why.
  131. Note that any code compiled -mips2 or higher already has this
  132. restriction built-in, and so should use method 2.
  133.  
  134. In general, it makes sense for all signal processing code to include
  135. one of these code snippets for better performance, since it doesn't
  136. hurt, and since underflows often come up unexpectedly.
  137.  
  138. - What Is Going On?
  139.  
  140. Note that on R4k's and above, method 1 ends up performing exactly the
  141. same Control Status Register operation as method 2, plus a lot of
  142. other unnecessary stuff.  Method 1 requires the application to link
  143. with libfpe.  This library was designed for use in trapping and
  144. debugging floating point exceptions, not silencing them.  For example,
  145. any app that links with libfpe must deal with several subtle and nasty
  146. side effects relating to signal handling.  This is why we strongly
  147. recommend the use of method 2 whenever possible.
  148.  
  149. But, as we mentioned, method 1 is the only solution available for R3k
  150. machines.  On R3k's, the code snippet above causes the interrupt
  151. handler for the underflow exception to clamp the underflowing value to
  152. zero.  This code does NOT prevent the FPU from issuing future
  153. underflow interrupts (these interrupts cannot be disabled on the R3k),
  154. but it does severely decrease the likelihood that you will run into
  155. serious performance degradations due to underflow.  This is because
  156. the underflows in a typical recursive filter come in large spans of
  157. several thousand underflows that occur before the accumulated value
  158. finally reaches zero.  This libfpe setting "catches" and clamps such
  159. underflow spans at the moment that they begin.  Note that we have used
  160. the constant _FLUSH_ZERO instead of _ZERO so that this snippet also
  161. solves the underflow problems on R4ks and beyond.  On R3ks,
  162. _FLUSH_ZERO and _ZERO are equivalent.
  163.  
  164. On R4k and later FPUs, method 1 and method 2 both set a bit on the FPU
  165. which prevents the FPU from issuing any trap on underflow.  The FPU
  166. quietly substitutes zero for the result of underflowing operations.
  167. Therefore, this setting is even more effective than it is on R3k's.
  168. It may still be less efficient than an algorithm which never
  169. underflows, though.  On processors later than R4k (R8k in fast mode,
  170. for example), this behavior may be the default, so you may never see
  171. the problem.
  172.  
  173. KNOWN BUGS:
  174.  
  175. In IRIX 5.3, two regressions occurred that did not exist in earlier
  176. IRIX releases.
  177.  
  178. R4600 CPUs: the libfpe library (and thus method 1) does not work at
  179. all on R4600s.  Any attempt to set libfpe options will result in a
  180. message about "unknown CPU type."  A patch is in the works for this.
  181. Contact your SGI service representative about possible patches for
  182. internal bug number 275803 or for libfpe.  You can also use method 2
  183. to get around this bug.
  184.  
  185. R3000 CPUs: the libfpe library (and thus method 1) does not work at
  186. all on R3000s.  Any attempt to set libfpe options will result in a
  187. message about "cause bits" and an abort (core dump).  A patch is in
  188. the works for this rather serious regression.  Contact your SGI
  189. service representative about possible patches for internal bug number
  190. 276012.  This bug is a kernel bug and requires a kernel patch.
  191. Programs that attempt to intercept SIGFPE directly (ie, not via
  192. libfpe) are also affected by this bug.  
  193.  
  194. NEW INFO: as of this writing, the fix for this R3000 bug made it into
  195. the R3000 kernel patch number 676, which has not yet been released.
  196. By the time you read this, there may be another higher-numbered R3000
  197. kernel patch that includes the fixes of patch 676 and other fixes too.
  198. Contact your SGI service representative to be sure.
  199.  
  200.