public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: How to use floating point in a module?
@ 2004-05-31 20:38 Manfred Spraul
  2004-05-31 21:11 ` Horst von Brand
  0 siblings, 1 reply; 24+ messages in thread
From: Manfred Spraul @ 2004-05-31 20:38 UTC (permalink / raw)
  To: Horst von Brand; +Cc: linux-kernel

Horst von Brand wrote:

>Trascendental functions are _not_ computed by series in practice, rational
>approximations (polinomial / polinomial) are used instead. Or interpolate
>in a smallish table.
>
Is that really faster on modern cpus? The multiplier is fully pipelined 
and a division takes 25-40 cycles.

--
    Manfred


^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
@ 2004-06-02  5:52 ndiamond
  2004-06-02 19:31 ` Valdis.Kletnieks
  0 siblings, 1 reply; 24+ messages in thread
From: ndiamond @ 2004-06-02  5:52 UTC (permalink / raw)
  To: linux-kernel

H. Peter Anvin replied to me:

>> (The CPU is an i686. I'll have to look up its opcodes and see if its
>> hardware will come close enough for everything the driver needs. If it
>> doesn't, I'll buy one of the books that some others kindly recommended
>> and do polynomial approximations.)
>
> On x86 (more specifically, on x87) if you can do it at all then you
> can do them all.

I'm not quite sure what that means.  It was pretty easy to code a log2()
function using the built-in opcode, but it took me nearly a day to code
an exp2() function.  The built-in f2xm1 opcode helps a lot but there's
no help for the other half exp2()'s lot.

I'm sure you and other x86 assembly experts can improve on this if
you ever have any need for it.  The only consolation I get is that
for some reason gcc does library calls for log10 and pow.  It would be
really trivial to inline log10, though maybe pow is too big to benefit
from inlining.

^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
@ 2004-06-01  2:27 ndiamond
  0 siblings, 0 replies; 24+ messages in thread
From: ndiamond @ 2004-06-01  2:27 UTC (permalink / raw)
  To: linux-kernel

Richard Johnson makes another enemy:

> Since you are using one of those
> Windows mailers and didn't enter a
> single end-of-line character,

The web-based mailer that I used for
submitting these behaves the same for
all Windows mailers including X11
Konqueror, X11 whatever Red Hat's
latest browser is, and XP IE.

> I detect that this is probably one
> of those trolls.

Good detective work.  I guess you were
looking in a mirror.

> Nevertheless, the use of floating-
> point is forbidden within the kernel.

That's why my first posting proposed a
method of getting the necessary results
without using floating-point hardware,
and my third posting reminded another
non-reader that my first posting said
what it said.

But then someone named Linus something-
or-other posted a reply saying that it
actually is possible to use the
floating-point hardware, within
some constraints.  But don't worry about
that, you didn't read my postings and
you won't read his.

Now I see why everyone hates you.

^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
@ 2004-06-01  0:38 ndiamond
  2004-06-01 20:52 ` H. Peter Anvin
  0 siblings, 1 reply; 24+ messages in thread
From: ndiamond @ 2004-06-01  0:38 UTC (permalink / raw)
  To: linux-kernel

In http://www.ussg.iu.edu/hypermail/linux/kernel/0405.3/1620.html,
Linus Torvalds wrote:

> You can do it "safely" on x86 using
> kernel_fpu_begin();
> ...
> kernel_fpu_end();
> and make sure that _all_ the FP stuff is in between those two things, and 
> that you don't do _anything_ that might fault or sleep.

In http://www.uwsg.iu.edu/hypermail/linux/kernel/0202.1/1591.html,
Alan Cox two years ago advised another questioner that init_fpu()
could be called after kernel_fpu_begin().  Looking at the source code,
this seems like a good idea.

Since the kernel is 2.4. 20something, init_fpu() takes no arguments.

I am looking at directory linux/arch/i386/kernel, with file i387.c
containing functions kernel_fpu_begin() and init_fpu() and others,
file i387.o resulting from a compilation, and Makefile saying that
i387 is included in the obj-y list.  So it seems to me that the executing
kernel should have kernel_fpu_begin() and init_fpu() built in.

But when we do insmod on our module, the list of undefined symbols
includes kernel_fpu_begin and init_fpu.  How is this possible?

(The CPU is an i686.  I'll have to look up its opcodes and see if its
hardware will come close enough for everything the driver needs.  If it
doesn't, I'll buy one of the books that some others kindly recommended
and do polynomial approximations.)  (By the way the driver is being
ported from VxWorks, where it seems that the kernel can do floating
point including trig, logarithms, etc.)


^ permalink raw reply	[flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
@ 2004-05-31  2:50 ndiamond
  2004-05-31  4:02 ` Chris Friesen
  2004-05-31  5:44 ` Ian Kent
  0 siblings, 2 replies; 24+ messages in thread
From: ndiamond @ 2004-05-31  2:50 UTC (permalink / raw)
  To: linux-kernel

Mans Rullgard replied to me:

>> A driver, implemented as a module, must do some floating-point
>> computations including trig functions.
>
>Sorry, floating point in the Linux kernel isn't allowed.

No.  Use of floating point HARDWARE, and/or emulation which emulates
troublesome features such as traps, isn't allowed.  Guess why I posted
in the first place, asking whether a certain combination of techniques
might be feasible.

>> Recompile GNU's libc with option "--without-fp".
>
>Probably, but it doesn't matter, since the kernel doesn't link with
>libc.

This unfortunate answer probably does answer my question, thank you.

>> Compile the module's .c files with gcc's "-msoft-float" option and
>> "-D__NO_MATH_INLINES". (Actually I think "-D__NO_MATH_INLINES" is
>> probably unnecessary here.)
>
>Using floating point emulation will be VERY slow.

No kidding.  And if I write my own code to do floating point emulation,
it will be even slower.  But if we do none of the above, then we should
say the result will be even slower because we will wait an infinite amount
of time without getting results.

>> Link the module's .o files with the version of libc produced above,
>> and try to get a loadable .ko from this... or a loadable .o since the
>> target is still kernel 2.4.something.
>
>As I said, the kernel doesn't link with libc.

Right, but is there a way to get a customized libc.a to link with a
module's .o and produce a loadable .o without damaging the rest of the
kernel.  I don't quite know a way.

>Floating point is forbidden in kernel code since the floating point
>registers (and other floating point context) is not saved/restored

No kidding, that's why use of floating point HARDWARE is prohibited.

>might be possible to manually save the floating point context while
>doing some floating point operations.

Yes, my searching found a few people saying they had found tricks like
this, but my impression is that it's very unreliable and they didn't
reveal their entire trickery (probably unteachable as mentioned).
I do think it is better to avoid the floating point hardware entirely.

>What you should do is think again about why you need all this floating
>point in the kernel.

To control a device.

>Could it be moved to userspace somehow?

Yes, if we use a real-time Linux and make a daemon cooperate very closely
with the driver.

>Maybe you could use lookup tables instead of doing floating point
>arithmetic.

You might be right, if the device can only be controlled to position itself
in say 1,000 different ways, then we could have lookup tables for 1,000
different intervals of (emulations of) floating-point numbers, that yield
1,000 different values of sin.  Another table for cos, another for log10,
etc.  But I'd still have to write my own emulations for binary operators
such as +, /, etc., since a 1,000*1,000 lookup table would be too big.

^ permalink raw reply	[flat|nested] 24+ messages in thread
* How to use floating point in a module?
@ 2004-05-31  1:52 ndiamond
  2004-05-31  2:18 ` Måns Rullgård
                   ` (4 more replies)
  0 siblings, 5 replies; 24+ messages in thread
From: ndiamond @ 2004-05-31  1:52 UTC (permalink / raw)
  To: linux-kernel

A driver, implemented as a module, must do some floating-point computations including trig functions.  Fortunately the architecture is x86.  A few hundred kilograms of searching (almost a ton of searching :-) seems to reveal the following possibilities.

Recompile GNU's libc with option "--without-fp".  If I understand correctly, the resulting libc will completely avoid using floating-point hardware while providing floating-point computations to its client.  Do I understand correctly?

Compile the module's .c files with gcc's "-msoft-float" option and "-D__NO_MATH_INLINES".  (Actually I think "-D__NO_MATH_INLINES" is probably unnecessary here.)

Link the module's .o files with the version of libc produced above, and try to get a loadable .ko from this... or a loadable .o since the target is still kernel 2.4.something.

But I'm sure there must be a ton of pitfalls that I'm not seeing here.  I'm not the first poor slob who got tasked with shoving some floating-point into a module.  My searches found a few tricks that people used for a few floating-point operations, but they used the real floating-point hardware and they didn't really reveal all the trickery they used.  (Not that I can blame them, since the hackery they did must be virtually unteachable.)  I didn't find anyone saying that they found a safe method of doing it, whether or not a safe method might somewhat resemble the ideas I've just presented.  I didn't find anyone saying they got trig functions into it either.  If my ideas could possibly work, surely they would have been done already.  So, what am I missing?

And does anyone know a really safe method?

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2004-06-02 19:31 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-31 20:38 How to use floating point in a module? Manfred Spraul
2004-05-31 21:11 ` Horst von Brand
  -- strict thread matches above, loose matches on Subject: below --
2004-06-02  5:52 ndiamond
2004-06-02 19:31 ` Valdis.Kletnieks
2004-06-01  2:27 ndiamond
2004-06-01  0:38 ndiamond
2004-06-01 20:52 ` H. Peter Anvin
2004-05-31  2:50 ndiamond
2004-05-31  4:02 ` Chris Friesen
2004-05-31  5:44 ` Ian Kent
2004-05-31  6:13   ` Peter Williams
2004-05-31 13:39   ` Horst von Brand
2004-05-31 20:12   ` Michal Jaegermann
2004-05-31 20:23     ` Hugo Mills
2004-05-31 22:43     ` Peter Williams
2004-05-31  1:52 ndiamond
2004-05-31  2:18 ` Måns Rullgård
2004-05-30 22:39   ` Calvin Spealman
2004-05-31  4:28   ` Linus Torvalds
2004-05-31  3:57     ` Calvin Spealman
2004-05-31  3:59 ` Matt Mackall
2004-05-31  4:11 ` Stephen Smoogen
2004-05-31 14:55 ` Scott Robert Ladd
2004-06-01  2:11 ` Richard B. Johnson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox