[Bug 192134]

Vincent-srcware 192134 at bugs.launchpad.net
Mon Mar 15 06:24:49 UTC 2021


(In reply to Petr Cervenka from comment #16)
> Simple workaround to use fast computation is to use functions from spec.
> header similar to following:
[long double versions: sinl, etc.]

This is not quite correct. These long double versions currently have a
lower worst-case time (this might change in the future), but in average
they are slower than the current double versions, with a factor around 5
- 6 from some tests on my machine. So, use this workaround only if you
want a better worst-case time, e.g. for real-time system (this is your
case[1], isn't it?).

[1] http://www.xenomai.org/pipermail/xenomai/2008-February/012416.html

The current library is slow, and libraries such as CRlibm could greatly
improve things, but hard-to-round cases would always be slower than the
average cases. So, the best implementation depends on the user's
application. I suppose that most users would be happy with a *good*
correctly rounded implementation since the loss due to correct rounding
should hardly be noticeable *in average* compared to an implementation
with just a very good accuracy (something close to 0.5 ulp). Then there
are users who accept to sacrifice correct rounding and accuracy for
faster functions. IMHO, the question is whether the GNU libc should
implement such variants and provide a way for the user to select them
(but this could mean other two variants or more[2]) or the user should
build his own library based on his own requirements, e.g. with tools
like MetaLibm[3] or other future tools.

[2] This should cover the accuracy for small arguments, but users may
also have different requirements concerning the range reduction (large
arguments).

[3] http://www.metalibm.org/

-- 
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to glibc in Ubuntu.
https://bugs.launchpad.net/bugs/192134

Title:
  slow math sin function for some values on amd64

Status in GLibC:
  Fix Released
Status in glibc package in Ubuntu:
  Triaged

Bug description:
  Hello.
  I have found that math sin function is unreasonable slow (400us on Athlon64  A2 4800+) for some values. It only happens on 64bit distribution.
  Used versions:
  Kubuntu 7.10 amd64 gutsy gutter
  linux kernel 2.6.24
  libc6           2.6.1-1ubuntu10
  libc6-dev     2.6.1-1ubuntu10

  Some of those values: -----------------------------------------------------------------------
  0.93340582292648832662962377071381	00 b0 6b e3 75 de ed 3f		0x3fedde75e36bb000
  2.3328432680770916363144351635128	d0 ad 38 bb a9 a9 02 40		0x4002a9a9bb38add0
  3.7439477503636453548097051680088	00 f5 cd e0 9a f3 0d 40		0x400df39ae0cdf500
  3.9225160069792437411706487182528	50 19 80 12 50 61 0f 40		0x400f615012801950
  4.0711651639931289992091478779912	20 dc 4f 85 df 48 10 40		0x401048df854fdc20
  4.7858438478542097982426639646292	c0 2f e9 3f b4 24 13 40		0x401324b43fe92fc0
  5.9840767662578002727968851104379	a0 52 df d1 b1 ef 17 40		0x4017efb1d1df52a0

  Short program for testing: ------------------------------------------------------------------
  #include <stdlib.h>
  #include <sstream>
  #include <iostream>
  #include <iomanip>
  #include <math.h>
  #include <sys/time.h>

  using namespace std;

  int main(int argc, char** argv) {
      
      volatile union {
          double dbl;
          unsigned char hex[sizeof(double)];
      } value;
      
      if (argc == sizeof(double)+1) {
          for (int i=0; i < sizeof(double); i++) {
              istringstream s(argv[i+1]);
              int tmp;
              s >> hex >> tmp;
              value.hex[i] = tmp;
          }
      } else if (argc == 2) {
          istringstream s(argv[1]);
          double tmp;
          s >> tmp;
          value.dbl = tmp;
      } else {
          cout << "usage: sintest 00 b0 6b e3 75 de ed 3f\n"
                  "       sintest 0.93340582292648832662962377071381";
          return (EXIT_FAILURE);
      }
      
      cout.precision(32);
      cout << value.dbl << endl;

      cout << "start\n";
      
      struct timeval time1, time2;
      gettimeofday(&time1, NULL);
      for (int i=0; i < 10000; i++) {
          volatile double out = sin(value.dbl);
      }
      gettimeofday(&time2, NULL);
      
      long long diftime = 1000000ll * (time2.tv_sec - time1.tv_sec) +
                           (time2.tv_usec - time1.tv_usec);
      
      cout << "end: " << diftime / 1000000ll << '.' << setw(6) << setfill('0') << diftime % 1000000ll << " s" << endl;
      
      return (EXIT_SUCCESS);
  }

  Petr Cervenka

To manage notifications about this bug go to:
https://bugs.launchpad.net/glibc/+bug/192134/+subscriptions



More information about the foundations-bugs mailing list