Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 01 Mar 1997 22:06:42 -0500
From:      Bakul Shah <bakul@chai.plexuscom.com>
To:        "David S. Miller" <davem@jenolan.rutgers.edu>
Cc:        dennis@etinc.com, dg@root.com, proff@suburbia.net, hackers@FreeBSD.ORG
Subject:   Re: optimised ip_input 
Message-ID:  <199703020306.WAA10813@chai.plexuscom.com>
In-Reply-To: Your message of "Sat, 01 Mar 1997 19:49:54 EST." <199703020049.TAA09426@jenolan.caipgeneral> 

next in thread | previous in thread | raw e-mail | index | archive | help
>    From: Bakul Shah <bakul@chai.plexuscom.com>

>   2) Profiling the networking code in a production environment ought
>      to point out the `hot spots' where much of the time is spent
>      under various conditions.  Measure various costs by changing data
>      structure sizes and feeding similar traffic.  Find out *why* the
>      hot spots are the way they are; gain a deeper understanding of
>      the structure and behavior of the networking code.

> Just a heads up, and this is from my own experience profiling this
> stuff.  For freely running connections (ie. application at receiving
> end or sending end is continually filling a healthy pipe which is
> being kept reasonably full) the kernel spends a significant portion of
> time in soreceive() and sosend().  Unfortunatly, last time I checked,
> those are not fun functions to hack on and optimize due to their
> complexity.

That is good to know.  Is this for Linux or for BSD derived stacks?
What does a finer grained profiling of so{receive,send} show?  It
would be interesting to know the top  time consuming functions that
add up to >90% of the time.

I don't see how complexity be reduced without some restructuring....

soreceive() has too many paths through it.  One trick to untangle
funtions like soreceive() is to fold parts of the function into
smaller inline functions.  May be some of these inline functions can
be used at the call sites of soreceive() so as to reduce the number
of arguments.  This in turn will obviate the need to decide in
soreceive() which code path to take.  Depending on what gets done in
the paths that are most common, one can also define two (or more)
specialized version of a function and cache a ptr to the appropriate
one in the caller's data structure.  While this sort of equivalent
transformations are not fun, what one learns about the needs of the
`clients' of a function is essential for the next step of a real
restructuring.  Also, this next step becomes somewhat easier, and
more fun thanks to the reduced clutter.

For some reason the BSD kernel seems to favor generalized functions
to specialized ones -- perhaps because decomposition of a big
function is costly if functions are used and error prone if macros
are used and inline functions are not a standard feature of C.
Anyway, using specialized functions one can much more easily
customize a system depending on its primary functions (a router/a
web-server for zillion addresses/address translation/ highly secure
communication/a plain old boring host etc.) without turning the
kernel into a kitchen sink.

-- bakul



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703020306.WAA10813>