All of lore.kernel.org
 help / color / mirror / Atom feed
* Why n_buckets is at least max_entries?
@ 2020-12-15 21:44 Cong Wang
  2020-12-15 22:17 ` Daniel Borkmann
  2020-12-16  1:45 ` Alexei Starovoitov
  0 siblings, 2 replies; 7+ messages in thread
From: Cong Wang @ 2020-12-15 21:44 UTC (permalink / raw)
  To: bpf; +Cc: Alexei Starovoitov

Hello,

Any reason why we allocate at least max_entries of buckets of a hash map?

 466
 467         /* hash table size must be power of 2 */
 468         htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);

This looks very odd to me, as I never see any other hash table
implementation like this. I _guess_ we try to make it a perfect hash?
But in reality no hash is perfect, so it is impossible to have no
conflicts, that is, there is almost always a bucket that has multiple
elements.

Or is it because other special maps (LRU?) require this? I can not
immediately see it from htab_map_alloc().

Thanks!

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Why n_buckets is at least max_entries?
  2020-12-15 21:44 Why n_buckets is at least max_entries? Cong Wang
@ 2020-12-15 22:17 ` Daniel Borkmann
  2020-12-16  1:45 ` Alexei Starovoitov
  1 sibling, 0 replies; 7+ messages in thread
From: Daniel Borkmann @ 2020-12-15 22:17 UTC (permalink / raw)
  To: Cong Wang, bpf; +Cc: Alexei Starovoitov

On 12/15/20 10:44 PM, Cong Wang wrote:
> Hello,
> 
> Any reason why we allocate at least max_entries of buckets of a hash map?
> 
>   466
>   467         /* hash table size must be power of 2 */
>   468         htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);
> 
> This looks very odd to me, as I never see any other hash table
> implementation like this. I _guess_ we try to make it a perfect hash?
> But in reality no hash is perfect, so it is impossible to have no
> conflicts, that is, there is almost always a bucket that has multiple
> elements.
> 
> Or is it because other special maps (LRU?) require this? I can not
> immediately see it from htab_map_alloc().

hash/LRU map is optimized for lookup speed, so __select_bucket() makes use
of the fact that it's power of 2.

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Why n_buckets is at least max_entries?
  2020-12-15 21:44 Why n_buckets is at least max_entries? Cong Wang
  2020-12-15 22:17 ` Daniel Borkmann
@ 2020-12-16  1:45 ` Alexei Starovoitov
  2020-12-16  1:55   ` Cong Wang
  1 sibling, 1 reply; 7+ messages in thread
From: Alexei Starovoitov @ 2020-12-16  1:45 UTC (permalink / raw)
  To: Cong Wang; +Cc: bpf, Alexei Starovoitov

On Tue, Dec 15, 2020 at 1:44 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
>
> Hello,
>
> Any reason why we allocate at least max_entries of buckets of a hash map?
>
>  466
>  467         /* hash table size must be power of 2 */
>  468         htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);

because hashmap performance matters a lot.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Why n_buckets is at least max_entries?
  2020-12-16  1:45 ` Alexei Starovoitov
@ 2020-12-16  1:55   ` Cong Wang
  2020-12-16  2:29     ` Alexei Starovoitov
  0 siblings, 1 reply; 7+ messages in thread
From: Cong Wang @ 2020-12-16  1:55 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: bpf, Alexei Starovoitov

On Tue, Dec 15, 2020 at 5:45 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Tue, Dec 15, 2020 at 1:44 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> >
> > Hello,
> >
> > Any reason why we allocate at least max_entries of buckets of a hash map?
> >
> >  466
> >  467         /* hash table size must be power of 2 */
> >  468         htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);
>
> because hashmap performance matters a lot.

Unless you believe hash is perfect, there is always conflict no matter
how many buckets we have.

Other hashmap implementations also care about performance, but none
of them allocates the number of buckets in this aggressive way. In some
particular cases, for instance max_entries=1025, we end up having almost
buckets twice of max_entries.

Thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Why n_buckets is at least max_entries?
  2020-12-16  1:55   ` Cong Wang
@ 2020-12-16  2:29     ` Alexei Starovoitov
  2020-12-16  2:39       ` Cong Wang
  0 siblings, 1 reply; 7+ messages in thread
From: Alexei Starovoitov @ 2020-12-16  2:29 UTC (permalink / raw)
  To: Cong Wang; +Cc: bpf, Alexei Starovoitov

On Tue, Dec 15, 2020 at 5:55 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
>
> On Tue, Dec 15, 2020 at 5:45 PM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Tue, Dec 15, 2020 at 1:44 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> > >
> > > Hello,
> > >
> > > Any reason why we allocate at least max_entries of buckets of a hash map?
> > >
> > >  466
> > >  467         /* hash table size must be power of 2 */
> > >  468         htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);
> >
> > because hashmap performance matters a lot.
>
> Unless you believe hash is perfect, there is always conflict no matter
> how many buckets we have.
>
> Other hashmap implementations also care about performance, but none
> of them allocates the number of buckets in this aggressive way. In some
> particular cases, for instance max_entries=1025, we end up having almost
> buckets twice of max_entries.

Do you have any numbers to prove that max_entries > 1024 with n_buckets == 1024
would still provide the same level of performance?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Why n_buckets is at least max_entries?
  2020-12-16  2:29     ` Alexei Starovoitov
@ 2020-12-16  2:39       ` Cong Wang
  2020-12-16 18:41         ` Alexei Starovoitov
  0 siblings, 1 reply; 7+ messages in thread
From: Cong Wang @ 2020-12-16  2:39 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: bpf, Alexei Starovoitov

On Tue, Dec 15, 2020 at 6:29 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Tue, Dec 15, 2020 at 5:55 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> >
> > On Tue, Dec 15, 2020 at 5:45 PM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Tue, Dec 15, 2020 at 1:44 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> > > >
> > > > Hello,
> > > >
> > > > Any reason why we allocate at least max_entries of buckets of a hash map?
> > > >
> > > >  466
> > > >  467         /* hash table size must be power of 2 */
> > > >  468         htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);
> > >
> > > because hashmap performance matters a lot.
> >
> > Unless you believe hash is perfect, there is always conflict no matter
> > how many buckets we have.
> >
> > Other hashmap implementations also care about performance, but none
> > of them allocates the number of buckets in this aggressive way. In some
> > particular cases, for instance max_entries=1025, we end up having almost
> > buckets twice of max_entries.
>
> Do you have any numbers to prove that max_entries > 1024 with n_buckets == 1024
> would still provide the same level of performance?

No, I assume you had when you added this implementation?

Also, it depends on what performance you are talking about too, the
lookup path is lockless so has nothing to do with the number of buckets.

The update path does content for bucket locks, but it is arguably the
slow path.

Thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Why n_buckets is at least max_entries?
  2020-12-16  2:39       ` Cong Wang
@ 2020-12-16 18:41         ` Alexei Starovoitov
  0 siblings, 0 replies; 7+ messages in thread
From: Alexei Starovoitov @ 2020-12-16 18:41 UTC (permalink / raw)
  To: Cong Wang; +Cc: bpf, Alexei Starovoitov

On Tue, Dec 15, 2020 at 06:39:26PM -0800, Cong Wang wrote:
> On Tue, Dec 15, 2020 at 6:29 PM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Tue, Dec 15, 2020 at 5:55 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> > >
> > > On Tue, Dec 15, 2020 at 5:45 PM Alexei Starovoitov
> > > <alexei.starovoitov@gmail.com> wrote:
> > > >
> > > > On Tue, Dec 15, 2020 at 1:44 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> > > > >
> > > > > Hello,
> > > > >
> > > > > Any reason why we allocate at least max_entries of buckets of a hash map?
> > > > >
> > > > >  466
> > > > >  467         /* hash table size must be power of 2 */
> > > > >  468         htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);
> > > >
> > > > because hashmap performance matters a lot.
> > >
> > > Unless you believe hash is perfect, there is always conflict no matter
> > > how many buckets we have.
> > >
> > > Other hashmap implementations also care about performance, but none
> > > of them allocates the number of buckets in this aggressive way. In some
> > > particular cases, for instance max_entries=1025, we end up having almost
> > > buckets twice of max_entries.
> >
> > Do you have any numbers to prove that max_entries > 1024 with n_buckets == 1024
> > would still provide the same level of performance?
> 
> No, I assume you had when you added this implementation?
> 
> Also, it depends on what performance you are talking about too, the
> lookup path is lockless so has nothing to do with the number of buckets.
> 
> The update path does content for bucket locks, but it is arguably the
> slow path.

The update/delete _is_ the fast path for many use cases.
Please see commit 6c9059817432 ("bpf: pre-allocate hash map elements")
Six! different implementation of prealloc were considered at that time.
Just as much, if not more, performance analysis went into LRU design.
See git log kernel/bpf/bpf_lru_list.c.
BPF was always laser focused on performance.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-12-16 18:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-15 21:44 Why n_buckets is at least max_entries? Cong Wang
2020-12-15 22:17 ` Daniel Borkmann
2020-12-16  1:45 ` Alexei Starovoitov
2020-12-16  1:55   ` Cong Wang
2020-12-16  2:29     ` Alexei Starovoitov
2020-12-16  2:39       ` Cong Wang
2020-12-16 18:41         ` Alexei Starovoitov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.