Skip to content

Conversation

@EgorBo
Copy link
Member

@EgorBo EgorBo commented Feb 2, 2024

This PR optimizes

span = x <= 64 ? stackalloc byte[n] : ...

to

span = x <= 64 ? stackalloc byte[64] : ...

because the latter is faster to zero (single instruction). Although, this consumes more stack, so the threshold is low.

Also, I need the generic optAssertionProp_GetInt32Range function in future opts I wanted to try.

Example:

static void Test(int n)
{
    Span<byte> span = (uint)n <= 64 ? stackalloc byte[n] : new byte[n];
    Consume(span);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void Consume(Span<byte> span){}

Codegen diff for Test(): https://www.diffchecker.com/s6pIRCSa/

@ghost ghost assigned EgorBo Feb 2, 2024
@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 2, 2024
@ghost
Copy link

ghost commented Feb 2, 2024

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

This PR optimizes

span = x < 64 ? stackalloc byte[n] : ...

to

span = x < 64 ? stackalloc byte[64] : ...

because the latter is faster to zero (single instruction). Although, this consumes more stack so the threshold is low.

Also, I need the generic optAssertionProp_GetInt32Range function in some other opts.

Author: EgorBo
Assignees: EgorBo
Labels:

area-CodeGen-coreclr

Milestone: -

@stephentoub
Copy link
Member

span = x <= 64 ? stackalloc byte[n] : ...
to
span = x <= 64 ? stackalloc byte[64] : ...

Does it slice it as well? Otherwise, that's a visible change that's almost guaranteed to break code that depended on span.Length being n rather than 64.

@EgorBo
Copy link
Member Author

EgorBo commented Feb 2, 2024

span = x <= 64 ? stackalloc byte[n] : ...
to
span = x <= 64 ? stackalloc byte[64] : ...

Does it slice it as well? Otherwise, that's a visible change that's almost guaranteed to break code that depended on span.Length being n rather than 64.

Right, it doesn't change that behaviour, my example is not entirely correct from C# point of view, but it gives the idea of what JIT does for it under the hood.

@EgorBo
Copy link
Member Author

EgorBo commented Feb 2, 2024

Also, this PR closes #81160 (although, I didn't plan it)

@jakobbotsch
Copy link
Member

What is the escape hatch for a user that truly wants to allocate as little stack as possible? In general I think we should be careful around changing stack consumption for patterns like this unless we have good evidence of benefits to motivate it (stack consumption vs execution speed is, as you say, a tradeoff)...

@EgorBo
Copy link
Member Author

EgorBo commented Feb 2, 2024

What is the escape hatch for a user that truly wants to allocate as little stack as possible? In general I think we should be careful around changing stack consumption for patterns like this unless we have good evidence of benefits to motivate it (stack consumption vs execution speed is, as you say, a tradeoff)...

This is just a draft to see the diffs. I wrote this function for a different opt, just noticed that it's a few lines of code to apply it for LCLHEAP. I don't have an answer on what threshold is safe to use to potentially increase stack usage for better perf.

@EgorBo
Copy link
Member Author

EgorBo commented Feb 2, 2024

Closing since I am not feeling confident enough to increase stack consumption in such functions.
I'll move my other changes to a separate PR and leave this as a history record

@EgorBo EgorBo closed this Feb 2, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Mar 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants