Re: schedule() "spaghetti" in 2.3.2 ..

Andi Kleen (ak@muc.de)
Mon, 17 May 1999 12:47:02 +0200


On Mon, May 17, 1999 at 12:22:53PM +0200, Davide Libenzi wrote:
> Hi Andi,
>
> why not move code blocks in macros ( like that in mm module ) or better in
> inline functions.

That would not have the intended effect - to keep jumps out of the
fast path.

Normally gcc codes a normal if like that (pseudo, m68k like assembly)

if (x < 0) {
/* error */
}
/* rest of fast path */

tst x
bgr L1 /* jump taken in most cases */
/* error */
L1:
/* rest of fast path */

this means there is a jump in the fast path (on modern CPUs that can be
quite costly because of the pipeline stall when the jump is mispredicted).
It is usually faster to have code like this:

if (x < 0)
goto error
/* rest of fast path *
return;

error:
/* error */

tst x
ble L1
....

ret
L1:
error

The untaken jump is cheap and unlikely to be mispredicted.
Most modern compiler do this automatically using "profile feedback" -
you profile the program first and compile again with the results,
then the compiler can make sure that there are no unnecessary jumps
in the common path. In the kernel this is not possible for several reasons
to do automatically
(the profiling technology is not here, gcc although supporting profiling
feedback in a limited fashion does not implement the necessary basic block
reordering),
so it is done by hand. The only way currently are these gotos.

inline functions and macros don't have that effect.

I would prefer a cleaner way too, e.g.

if (__builtin_predict(err < 0, 0)) {
/* unlikely error code */
}

to tell the compiler that it should move the error code out of line.
But currently Linux kernel has to work with existing compilers, which
means 2.7.2.

-Andi

-- 
This is like TV. I don't like TV.

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/