Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Jul 2001 09:45:29 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        "Albert D. Cahalan" <acahalan@cs.uml.edu>
Cc:        freebsd-hackers@FreeBSD.ORG, Jim.Pirzyk@disney.com
Subject:   Re: math library difference between linux emulation and native freebsd   (and native linux)
Message-ID:  <3B546BA9.37E9F437@mindspring.com>
References:  <200107170615.f6H6FU5376195@saturn.cs.uml.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
"Albert D. Cahalan" wrote:
> >> There are only two shared libaries in common (libc and libm) and
> >> both are the same on FreeBSD (in /compat/linux) and Linux.
> >>
> >> So any ideas on where the program is going wrong?
> >
> > man fpsetround
> 
> That won't change a thing. Both systems round to nearest.

Look at the other items on that man page, as well.  I
didn't list them all.


> > The defaults for the Linux emulator are different than
> > the defaults for Linux.  Linux sets some stuff up wrong,
> 
> FreeBSD sets stuff up wrong. This is a choice between bad
> and worse, since the CPU does not support what you want.

FreeBSD complies strictly with the IEEE FP standard.

Linux fails to set 0x37f into the mask before doing
its calculations, and assumes that the OS has done this
for it.  In Linux it's true, in the emulator, it's not;
the fix is obvious: somone who uses the Linux emulator
should fix this.

One obvious reason that the Linux approach is wrong is
that it ends up requiring the save and restore of FP
registers on context switches, which is overhead they
ate anyway, by doing TSS based context switching.  The
amount of state with SSE is up to something like an
additional 512 bytes -- that's ungodly overhead, since
most programs don't use this context at all.


> An x86 CPU has a rounding precision that may be set for
> float, double, or long double. FreeBSD sets the CPU to
> make double work, giving extra fraction bits for float
> and truncating long double. Linux sets the CPU to make
> long double work, giving extra fraction bits for both
> float and long double. Now what is worse, getting some
> extra bits in an intermediate calculation or truncation?
> Note that the FreeBSD setting causes _both_ problems.

FreeBSD's settings do not cause problems for FreeBSD; as
has been observed in this thread, FreeBSD gets the right
answer when you run the code native, just as Linux does;
the emulator gets the wrong answer, but the problem is
really the programs assuming that the mask will be set
by the OS to the "magic" correct value.

As also noted in this thread, Mathematica under the Linux
emulator gets the _right_ answer.  Clearly, the authors
of Mathematica know to not make ignorant assumptions about
the default state of hardware.


> See float_t, double_t, FLT_EVAL_METHOD and FLT_ROUNDS in
> the 1999 C standard for ways to deal with x86 hardware.

The standards are not x86 specific; the fp*() functions
are.

It is probably worthwhile to solve this problem by doing
a "brand" of floating point using Linux binaries, rather
than eating the additional context switch overhead for
all Linux programs... there _are_ reasons that Linux
binaries running on the FreeBSD Linux ABI are frequently
faster than when running natively on Linux.


-- Terry

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3B546BA9.37E9F437>