* 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-05-31 20:38 How to use floating point in a module? Manfred Spraul
@ 2004-05-31 21:11 ` Horst von Brand
0 siblings, 0 replies; 24+ messages in thread
From: Horst von Brand @ 2004-05-31 21:11 UTC (permalink / raw)
To: Manfred Spraul; +Cc: linux-kernel
Manfred Spraul <manfred@colorfullife.com> said:
> 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.
You need smallish polinomials for double precision, via series it would
take you a lot more terms (and then you get trouble from rounding etc).
No, numerical computation is not my main interest. I might be wrong here.
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria +56 32 654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513
^ 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-06-01 0:38 ndiamond
@ 2004-06-01 20:52 ` H. Peter Anvin
0 siblings, 0 replies; 24+ messages in thread
From: H. Peter Anvin @ 2004-06-01 20:52 UTC (permalink / raw)
To: linux-kernel
Followup to: <200406010038.i510cxk23507@mailout.despammed.com>
By author: ndiamond@despammed.com
In newsgroup: linux.dev.kernel
>
> (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.)
>
On x86 (more specifically, on x87) if you can do it at all then you
can do them all. All that really means is that the fp library is in
microcode on x87.
-hpa
^ 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
* 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
1 sibling, 0 replies; 24+ messages in thread
From: Chris Friesen @ 2004-05-31 4:02 UTC (permalink / raw)
To: ndiamond; +Cc: linux-kernel
ndiamond@despammed.com wrote:
> Mans Rullgard replied to me:
> >What you should do is think again about why you need all this floating
> >point in the kernel.
>
> To control a device.
Note that there is nothing stopping you from doing fixed-point math in
the kernel. Depending on the application, this may be sufficient.
Chris
^ 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
2004-05-31 6:13 ` Peter Williams
` (2 more replies)
1 sibling, 3 replies; 24+ messages in thread
From: Ian Kent @ 2004-05-31 5:44 UTC (permalink / raw)
To: ndiamond; +Cc: linux-kernel
On Sun, 30 May 2004 ndiamond@despammed.com wrote:
>
> 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.
Why not scaled longs (or bigger), scalled to number of significant
digits. The Taylor series for the trig functions might be a painfull.
Ian
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: How to use floating point in a module?
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
2 siblings, 0 replies; 24+ messages in thread
From: Peter Williams @ 2004-05-31 6:13 UTC (permalink / raw)
To: Ian Kent; +Cc: ndiamond, linux-kernel
Ian Kent wrote:
> On Sun, 30 May 2004 ndiamond@despammed.com wrote:
>
>
>>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.
>
>
> Why not scaled longs (or bigger), scalled to number of significant
> digits. The Taylor series for the trig functions might be a painfull.
See the "Handbook of Mathematical Functions" by Abromawitz and Stegun,
Dover Publications (ISBN 486-61272-2, Library of Congress number
65-12253) which has some small but accurate polynomial approximations
for many functions. I have used these successfully with fixed point
rational numbers (FDRN) (which are probably the same as your scaled
longs) using 64 bit integers and the results were generally accurate to
the least significant bit when compared to values calculated using the
normal maths library and converted to FDRN representation.
Of course, the available range of values is smaller than for floats or
double and you have to be careful w.r.t. overflow etc.
Peter
--
Dr Peter Williams pwil3058@bigpond.net.au
"Learning, n. The kind of ignorance distinguishing the studious."
-- Ambrose Bierce
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
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
2 siblings, 0 replies; 24+ messages in thread
From: Horst von Brand @ 2004-05-31 13:39 UTC (permalink / raw)
To: Ian Kent; +Cc: ndiamond, linux-kernel
Ian Kent <raven@themaw.net> said:
[...]
> Why not scaled longs (or bigger), scalled to number of significant
> digits. The Taylor series for the trig functions might be a painfull.
Trascendental functions are _not_ computed by series in practice, rational
approximations (polinomial / polinomial) are used instead. Or interpolate
in a smallish table.
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria +56 32 654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
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
2 siblings, 2 replies; 24+ messages in thread
From: Michal Jaegermann @ 2004-05-31 20:12 UTC (permalink / raw)
To: Ian Kent; +Cc: linux-kernel
On Mon, May 31, 2004 at 01:44:40PM +0800, Ian Kent wrote:
>
> Why not scaled longs (or bigger), scalled to number of significant
> digits. The Taylor series for the trig functions might be a painfull.
Taylor series usually are painful for anything you want to calculate
by any practical means. Slow convergence but, for a change, quickly
growing roundup errors and things like that. An importance and uses
of Taylor series lie elsewhere.
OTOH polynomial approximations, or rational ones (after all division
is quite quick on modern processors), can be fast and surprisingly
precise; especially if you know bounds for your arguments and that
that range is not too wide. Of course when doing that in a fixed
point one needs to pay attention to possible overflows and
structuring calculations to guard against a loss of precision is
always a good idea.
My guess is that finding some fixed-point libraries, at least to use
as a starting point, should be not too hard.
Michal
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
2004-05-31 20:12 ` Michal Jaegermann
@ 2004-05-31 20:23 ` Hugo Mills
2004-05-31 22:43 ` Peter Williams
1 sibling, 0 replies; 24+ messages in thread
From: Hugo Mills @ 2004-05-31 20:23 UTC (permalink / raw)
To: Michal Jaegermann; +Cc: Ian Kent, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1452 bytes --]
On Mon, May 31, 2004 at 02:12:53PM -0600, Michal Jaegermann wrote:
> On Mon, May 31, 2004 at 01:44:40PM +0800, Ian Kent wrote:
> >
> > Why not scaled longs (or bigger), scalled to number of significant
> > digits. The Taylor series for the trig functions might be a painfull.
>
> Taylor series usually are painful for anything you want to calculate
> by any practical means. Slow convergence but, for a change, quickly
> growing roundup errors and things like that. An importance and uses
> of Taylor series lie elsewhere.
>
> OTOH polynomial approximations, or rational ones (after all division
> is quite quick on modern processors), can be fast and surprisingly
> precise; especially if you know bounds for your arguments and that
> that range is not too wide. Of course when doing that in a fixed
> point one needs to pay attention to possible overflows and
> structuring calculations to guard against a loss of precision is
> always a good idea.
It's also worth pointing out that there are other, much
faster-converging, polynomial series that can be used to approximate
trig functions. Chebyshev polynomials are, I believe, pretty
well-behaved. IIRC, they are what the Sinclair Spectrum used to use.
Hugo.
--
=== Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk ===
PGP key: 1C335860 from wwwkeys.eu.pgp.net or http://www.carfax.org.uk
--- Hey, Virtual Memory! Now I can have a *really big* ramdisk! ---
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
2004-05-31 20:12 ` Michal Jaegermann
2004-05-31 20:23 ` Hugo Mills
@ 2004-05-31 22:43 ` Peter Williams
1 sibling, 0 replies; 24+ messages in thread
From: Peter Williams @ 2004-05-31 22:43 UTC (permalink / raw)
To: Michal Jaegermann; +Cc: Ian Kent, linux-kernel
Michal Jaegermann wrote:
> On Mon, May 31, 2004 at 01:44:40PM +0800, Ian Kent wrote:
>
>>Why not scaled longs (or bigger), scalled to number of significant
>>digits. The Taylor series for the trig functions might be a painfull.
>
>
> Taylor series usually are painful for anything you want to calculate
> by any practical means. Slow convergence but, for a change, quickly
> growing roundup errors and things like that. An importance and uses
> of Taylor series lie elsewhere.
>
> OTOH polynomial approximations, or rational ones (after all division
> is quite quick on modern processors), can be fast and surprisingly
> precise; especially if you know bounds for your arguments and that
> that range is not too wide. Of course when doing that in a fixed
> point one needs to pay attention to possible overflows and
> structuring calculations to guard against a loss of precision is
> always a good idea.
>
> My guess is that finding some fixed-point libraries, at least to use
> as a starting point, should be not too hard.
See the "Handbook of Mathematical Functions" by Abromawitz and Stegun,
Dover Publications (ISBN 486-61272-2, Library of Congress number
65-12253) which has some small but accurate polynomial approximations
for many functions.
--
Dr Peter Williams, Chief Scientist peterw@aurema.com
Aurema Pty Limited Tel:+61 2 9698 2322
PO Box 305, Strawberry Hills NSW 2012, Australia Fax:+61 2 9699 9174
79 Myrtle Street, Chippendale NSW 2008, Australia http://www.aurema.com
^ 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* Re: How to use floating point in a module?
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:59 ` Matt Mackall
` (3 subsequent siblings)
4 siblings, 2 replies; 24+ messages in thread
From: Måns Rullgård @ 2004-05-31 2:18 UTC (permalink / raw)
To: linux-kernel
ndiamond@despammed.com writes:
> 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.
> 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?
Probably, but it doesn't matter, since the kernel doesn't link with
libc.
> 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.
> 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.
> 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?
Floating point is forbidden in kernel code since the floating point
registers (and other floating point context) is not saved/restored
during system calls, for efficiency. I'm speculating here, but it
might be possible to manually save the floating point context while
doing some floating point operations. The problem arises if this code
is interrupted midway. Using a preemptive 2.6 kernel would easily
break here.
What you should do is think again about why you need all this floating
point in the kernel. Could it be moved to userspace somehow? Maybe
you could use lookup tables instead of doing floating point
arithmetic.
--
Måns Rullgård
mru@kth.se
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: How to use floating point in a module?
2004-05-31 2:18 ` Måns Rullgård
@ 2004-05-30 22:39 ` Calvin Spealman
2004-05-31 4:28 ` Linus Torvalds
1 sibling, 0 replies; 24+ messages in thread
From: Calvin Spealman @ 2004-05-30 22:39 UTC (permalink / raw)
To: linux-kernel
Måns Rullgård wrote:
> Floating point is forbidden in kernel code since the floating point
> registers (and other floating point context) is not saved/restored
> during system calls, for efficiency. I'm speculating here, but it
> might be possible to manually save the floating point context while
> doing some floating point operations. The problem arises if this code
> is interrupted midway. Using a preemptive 2.6 kernel would easily
> break here.
What about adding some functions such as enable_fpreg_syscalls() and
disable_fpreg_syscalls() that could be called before and after any floating
point operations? They could set a flag somewhere that would cause the
float registers to be saved/restored. Forgive me if this is somehow stupid.
I'm very much a kernel newbie.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
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
1 sibling, 1 reply; 24+ messages in thread
From: Linus Torvalds @ 2004-05-31 4:28 UTC (permalink / raw)
To: Måns Rullgård; +Cc: linux-kernel
On Mon, 31 May 2004, Måns Rullgård wrote:
>
> Floating point is forbidden in kernel code since the floating point
> registers (and other floating point context) is not saved/restored
> during system calls, for efficiency. I'm speculating here, but it
> might be possible to manually save the floating point context while
> doing some floating point operations. The problem arises if this code
> is interrupted midway. Using a preemptive 2.6 kernel would easily
> break here.
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.
The kernel_fpu_xxx() macros make sure that preemption is turned off etc,
so the above should always be safe.
Even then, of course, using FP in the kernel assumes that you actually
_have_ an FPU, of course. The in-kernel FP emulation package is _not_
supposed to work with kernel FP instructions.
Oh, and since the kernel doesn't link with libc, you can't use anything
even remotely fancy. It all has to be stuff that gcc can do in-line,
without any function calls.
In other words: the rule is that you really shouldn't use FP in the
kernel. There are ways to do it, but they tend to be for some _real_
special cases, notably for doing MMX/XMM work. Ie the only "proper" FPU
user is actually the RAID checksumming MMX stuff.
Linus
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
2004-05-31 1:52 ndiamond
2004-05-31 2:18 ` Måns Rullgård
@ 2004-05-31 3:59 ` Matt Mackall
2004-05-31 4:11 ` Stephen Smoogen
` (2 subsequent siblings)
4 siblings, 0 replies; 24+ messages in thread
From: Matt Mackall @ 2004-05-31 3:59 UTC (permalink / raw)
To: ndiamond; +Cc: linux-kernel
On Sun, May 30, 2004 at 08:52:23PM -0500, ndiamond@despammed.com wrote:
> 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.
[bizarre method deleted]
How about:
mask off interrupts locally
save floating point state
do floating point work
restore floating point state
restore interrupt mask
You will need to take care that you keep gcc from using library
functions, see the gcc manual.
Another approach is to do it all in fixed point, which is a simple
matter of doing some shifts after your multiplies. This only works if
you've got a fairly small dynamic range, but if you only need to
calculate a sine or two, it's not too painful and you can have about
8-10 decimal digits of accuracy. Or you can go quick and dirty with a
piecewise polynomial approximation for 2-5 digits of accuracy.
--
Mathematics is the supreme nostalgia of our time.
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: How to use floating point in a module?
2004-05-31 1:52 ndiamond
2004-05-31 2:18 ` Måns Rullgård
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
4 siblings, 0 replies; 24+ messages in thread
From: Stephen Smoogen @ 2004-05-31 4:11 UTC (permalink / raw)
To: linux-kernel
On Sun, 30 May 2004 ndiamond@despammed.com wrote:
>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.
How much precision do you need for you hardware device? It would
probably be easier to use 1 to 2 precision point old integer approx
equations for what you are wanting. However, it is probably the worst
thing to do by putting that much overhead into kernel space. In the end,
if you are needing tight control anyway, a real time kernel would be a
better match for your requirements. Keep the hardware as simple as
possible (or put the calculations into the sub-hardware piece).
--
Stephen John Smoogen smoogen@lanl.gov
Los Alamos National Lab CCN-5 Sched 5/40 PH: 4-0645
Ta-03 SM-1498 MailStop B255 DP 10S Los Alamos, NM 87545
-- You should consider any operational computer to be a security problem --
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: How to use floating point in a module?
2004-05-31 1:52 ndiamond
` (2 preceding siblings ...)
2004-05-31 4:11 ` Stephen Smoogen
@ 2004-05-31 14:55 ` Scott Robert Ladd
2004-06-01 2:11 ` Richard B. Johnson
4 siblings, 0 replies; 24+ messages in thread
From: Scott Robert Ladd @ 2004-05-31 14:55 UTC (permalink / raw)
To: linux-kernel
ndiamond@despammed.com wrote:
> And does anyone know a really safe method?
I recently built a 64-bit fixed-point library for a client, which they
used in a device driver. I'd suggest following a similar pattern, thus
avoiding the entire issues of "floating-point" in the kernel.
..Scott
--
Scott Robert Ladd
Coyote Gulch Productions (http://www.coyotegulch.com)
Software Invention for High-Performance Computing
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: How to use floating point in a module?
2004-05-31 1:52 ndiamond
` (3 preceding siblings ...)
2004-05-31 14:55 ` Scott Robert Ladd
@ 2004-06-01 2:11 ` Richard B. Johnson
4 siblings, 0 replies; 24+ messages in thread
From: Richard B. Johnson @ 2004-06-01 2:11 UTC (permalink / raw)
To: ndiamond; +Cc: linux-kernel
On Sun, 30 May 2004 ndiamond@despammed.com wrote:
> 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.
>
Since you are using one of those Windows mailers and didn't enter a
single end-of-line character, I detect that this is probably one
of those trolls. Nevertheless, the use of floating-point is forbidden
within the kernel. Period. Because anybody who thinks they need
floating-point mathematics within the kernel is completely without
a clue, the floating-point context is not saved/restored during system
calls.
You must pair a user-mode program (usually called a daemon) with
the kernel-mode interface to your hardware (your module). This
combination will provide whatever functionality you require. The
user-mode daemon does the math and probably a lot of other things
as well.
Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5583.66 BogoMips).
Note 96.31% of all statistics are fiction.
^ 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