Skip to content

Performance: Layout::align() can assume, that the alignment is a power of two #75264

Open
@TimDiekmann

Description

@TimDiekmann

An alignment is guaranteed to be a power of two. However without intrinsics it's not possible to use this guarantee when constructing a new Layout from an old one only changing the size. For testing I used the following code:

pub fn dynamic_slow(layout: Layout, size: usize) -> Result<Layout, LayoutErr>{
    let align = layout.align();
    Layout::from_size_align(size, align)
}

pub fn dynamic_fast(layout: Layout, size: usize) -> Result<Layout, LayoutErr>{
    let align = layout.align();
    unsafe { core::intrinsics::assume(align.is_power_of_two()); }
    Layout::from_size_align(size, align)
}

pub fn static_slow() -> Result<Layout, LayoutErr> {
    dynamic_slow(Layout::new::<u32>(), 12)
}

pub fn static_fast() -> Result<Layout, LayoutErr> {
    dynamic_fast(Layout::new::<u32>(), 12)
}

dynamic_fast assumes, that the alignment returned from Layout is a power of two. This results in this assembly:

example::dynamic_slow:
        lea     rax, [rsi - 1]
        mov     r8, rsi
        neg     r8
        xor     ecx, ecx
        test    rsi, rax
        mov     rdi, rsi
        cmovne  rdi, rcx
        test    rsi, rsi
        cmove   rdi, rsi
        mov     rax, rdx
        cmp     r8, rdx
        cmovae  rcx, rdi
        mov     rdx, rcx
        ret

example::dynamic_fast:
        mov     rax, rdx
        mov     rcx, rsi
        neg     rcx
        xor     edx, edx
        cmp     rcx, rax
        cmovae  rdx, rsi
        ret

example::static_slow:
        mov     eax, 12
        mov     edx, 4
        ret

example::static_fast:
        mov     eax, 12
        mov     edx, 4
        ret

While in the static case, this does not matter, the dynamic case don't have to check align.is_power_of_two().

Normally, I would create a pull request, which adds the intrinsic to Layout::align(), but core::intrinsics::assume is not available in const fns.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-allocatorsArea: Custom and system allocatorsC-enhancementCategory: An issue proposing an enhancement or a PR with one.I-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions