Re: [patch 4/9] slab: cache_estimate cleanup
From: Steven Rostedt
Date: Wed Jan 04 2006 - 09:11:26 EST
On Tue, 2006-01-03 at 20:47 -0500, Steven Rostedt wrote:
> >
> > I've also been looking at this and I've realized that we can even remove
> > the "while" and make it into an "if". It works just as well. I created
> > the attached test program to see if there would be any difference
> > testing all sizes from 8 to PAGE_SIZE >> 1 (where PAGE_SIZE = 1<<12),
> > and all alignments of 4 to size, and I tried this with two orders of
> > pages. The "if" should make the assembly a little better.
> >
> >
[...]
> +static size_t slab_mgmt_size(size_t nr_objs, size_t align)
> {
[ delete deletion ]
> + return ALIGN(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t), align);
> +}
> +
> +/* Calculate the number of objects and left-over bytes for a given
> + object size. */
> +static void cache_estimate(unsigned long gfporder, size_t obj_size,
> + size_t align, int flags, size_t *left_over,
> + unsigned int *num)
> +{
> +
[...]
> + /* Ignore padding for the initial guess. The padding
> + * is at most @align-1 bytes, and @size is at least
> + * @align. In the worst case, this result will be one
> + * greater than the number of objects that fit into
> + * the memory allocation when taking the padding into
> + * account.
> + */
> + nr_objs = (slab_size - sizeof(struct slab)) /
> + (obj_size + sizeof(kmem_bufctl_t));
> +
> + /*
> + * This calculated number will be either the right
> + * amount, or one greater than what we want.
> + */
> + if (slab_mgmt_size(nr_objs, align) + nr_objs*obj_size
> + > slab_size)
> + nr_objs--;
No while is needed! slab_mgmt_size(nr_objs, align) will end up being:
(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t)+align-1)&~(align-1)
lets say:
S = sizeof(struct slab)
K = sizeof(kmem_bufctl_t)
n = nr_objs
z = slab_size
o = objsize
a = align
nr_objs = (slab_size - sizeof(struct slab)) /
(size + sizeof(kmem_bufctl_t));
will be n = (z - S) / (o + K)
looking at the if:
if (slab_mgmt_size(nr_objs, align) + nr_objs*size
> slab_size)
and slab_mgmt_size:
static size_t slab_mgmt_size(size_t nr_objs, size_t align)
{
return ALIGN(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t), align);
}
and ALIGN:
#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
slab_mgmt_size is the same as:
ALIGN(S + nK, a)
so this will not be greater than:
S + nK + a - 1
add this to the if:
if (S + nK + a-1 + no > z)
proof by contradiction: can the left side be greater than z + o?
S + nK + a-1 + no = z+o+1 ?
S + (o+K)n + a-1 = z+o+1
n = (z - S) / (o + K) so:
S + (o+K)(z-S)/(o+K) + a-1 = z+o+1
S + (z-S) + a-1 = z+o+1
removing the z and S
a-1 = o+1
We know that a can be at most o so:
o-1 = o+1
and thus we get:
-1 = 1
So I believe this is the proof by contradiction. Might want to check
this, since I just woke up ;)
-- Steve
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/