Thread (13 messages) 13 messages, 5 authors, 2021-11-02

Re: [PATCH v2 2/2] btrfs: use ilog2() to replace if () branches for btrfs_bg_flags_to_raid_index()

From: Qu Wenruo <hidden>
Date: 2021-10-27 07:41:31


On 2021/10/27 14:37, Nikolay Borisov wrote:

On 27.10.21 г. 8:28, Qu Wenruo wrote:
quoted
In function btrfs_bg_flags_to_raid_index(), we use quite some if () to
convert the BTRFS_BLOCK_GROUP_* bits to a index number.

But the truth is, there is really no such need for so many branches at
all.
Since all BTRFS_BLOCK_GROUP_* flags are just one single bit set inside
BTRFS_BLOCK_GROUP_PROFILES_MASK, we can easily use ilog2() to calculate
their values.

Only one fixed offset is needed to make the index sequential (the
lowest profile bit starts at ilog2(1 << 3) while we have 0 reserved for
SINGLE).

Even with that calculation involved (one if(), one ilog2(), one minus),
it should still be way faster than the if () branches, and now it is
definitely small enough to be inlined.
Is this used in a performance critical path,
Not really in a hot path.

Most of them are called in a per block group/chunk base.

The only hotter path is in __btrfs_map_block() where if we need full
stripe, we will call btrfs_chunk_max_errors() which in turn call the
function.

That's the hottest path I can find, and even for that case it's just
per-bio base.
are there any numbers which prove that it's indeed faster?
No real world bench for it.

But from x86_75 asm code, it's definitely smaller, with only one branch.

New:
btrfs_bg_flags_to_raid_index:
         xorl    %eax, %eax
         andl    $2040, %edi
         je      .L2499
         shrq    $2, %rdi
         movl    $-1, %eax
         bsrq %rdi,%rax
.L2499:
         ret

Old:
btrfs_bg_flags_to_raid_index:
         xorl    %eax, %eax
         testb   $64, %dil
         jne     .L429
         movl    $1, %eax
         testb   $16, %dil
         jne     .L429
         movl    $7, %eax
         testl   $512, %edi
         jne     .L429
         movl    $8, %eax
         testl   $1024, %edi
         jne     .L429
         movl    $2, %eax
         testb   $32, %dil
         jne     .L429
         movl    $3, %eax
         testb   $8, %dil
         jne     .L429
         movl    $5, %eax
         testb   $-128, %dil
         jne     .L429
         andl    $256, %edi
         cmpq    $1, %rdi
         sbbl    %eax, %eax
         andl    $-2, %eax
         addl    $6, %eax
.L429:
         ret

Which I don't really believe the older code can be any faster,
considering so many branches, and pure lines of asm.

Thanks,
Qu
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help