Floating point operations in kernel

Hello.

As I wrote a few posts ago, I’m developing a minifilter to do some analysis on the File System (but I think that the question I’m goind to do is suitable for NTDEV).

So, my problem arise when I want to evaluate a logarithm. I read that floating points operations should be taken out with particular care at kernel level, and I read that I should use the KeSaveFloatingPointState and KeRestoreFloatingPointState routines during each floating point operations. I suppose that one of the question that will arise is “Do you really need floating point operations?”, and since I need to evaluate entropy of a file I need it. So, 3 question arises:

  1. Why floating point operations are not permitted at kernel level? Is it because when a kernel-kernel context switch happens the state of FP registers is not saved, while it is saved in a user-kernel transition (feel free to correct if wrong)?

  2. Should I use KeSave and KeRestore between each block of floating point operation or between each instruction? For example in http://pastebin.com/80kqUsyN which is the right one? Solution 1 or 2?

  3. Is there any way I can use the log inside math.h function inside my minifilter? If not, is there any other way to implement a log operation?

Many thanks in advance

xxxxx@gmail.com wrote:

I suppose that one of the question that will arise is “Do you really need floating point operations?”, and since I need to evaluate entropy of a file I need it. So, 3 question arises:

  1. Why floating point operations are not permitted at kernel level? Is it because when a kernel-kernel context switch happens the state of FP registers is not saved, while it is saved in a user-kernel transition (feel free to correct if wrong)?

Correct. In the early days of the NT kernel, when we were using 80387
co-processors, saving the FPU state was an extremely expensive operation
– many thousands of CPU cycles. The design decision was made at that
point to skip it for kernel transitions. Once made, such a decision
cannot be easily rescinded.

  1. Should I use KeSave and KeRestore between each block of floating point operation or between each instruction? For example in http://pastebin.com/80kqUsyN which is the right one? Solution 1 or 2?

You should be able to figure this out. The purpose of calling save and
restore is not to protect YOUR data. The purpose is to protect the
threads that were running before you. So, save before you get called,
and restore before you return. As long as everybody follows that rule,
your registers will survive.

  1. Is there any way I can use the log inside math.h function inside my minifilter? If not, is there any other way to implement a log operation?

There are many ways. The “libcntpr.lib” library provides a nearly
complete implementation of the C run-time library for kernel drivers.
It includes log and log10. If you are 32-bit only, you can use inline
assembler. If all else fails, you can implement a logarithm using a
Taylor series polynomial, which is the same thing the FPU chip uses.

However, you also might take a step back and figure out whether you need
logarithms at all. You can approximate log(2) rather easily by using
simple bit mask operations on a floating point value. If you are simply
comparing two values, it makes no difference whether you compare the
values or the log of those values.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim.

Many thanks for your help. Unfortunately I really need the log calculation, and a rather precise one probably. Right now I’m still on a testing phase, but I won’t probably be able to avoid using logarithmic operations.

xxxxx@gmail.com wrote:

Many thanks for your help. Unfortunately I really need the log calculation, and a rather precise one probably. Right now I’m still on a testing phase, but I won’t probably be able to avoid using logarithmic operations.

That’s quite possible, and I showed you several paths to make that
work. I just want to make sure that you don’t forget to stand back once
in a while to think about your problem in other ways. I can’t count the
number of times I’ve encountered situations where time-consuming but
highly accurate algorithms could be replaced by simpler algorithms with
no loss of functionality. A simple integer look-up table can often
replace a floating trig function. Heck, just the binary representation
of floating point numbers themselves gives you a first approximation to
a log base 2.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> replace a floating trig function. Heck, just the binary representation

of floating point numbers themselves gives you a first approximation to
a log base 2.

And yes, often uint64_t is preferrable over the floating point.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com