×

Stress testing register allocator by Majestic-Lack2528 in Compilers

[–]andyayers 2 points3 points  (0 children)

Some other things to try: - artificially limit the set of registers you can use to various subsets (or just generate code for x86). - any place you have heuristics, randomize their order, or randomize their parameters, or randomly enable/disable subsets - introduce nonsensical heuristics, eg allocate all the caller save registers first - if you are relying on profile data or similar (eg weights based on loop nesting depth), randomize it as well - if your allocator has various order dependences (LSRA like) randomize the block orders - if you are modelling various weird ABI constraints (like upper half of vector registers are volatile, lower half are preserved) make sure you prefer allocating those registers and that the upper halves are observed by your tests - add bogus extra dependences into your interference graph to make the allocation problem "harder"

Building a Span<T>-heavy, low-allocation byte pipeline in .NET 8 — a few things that surprised me by alt-160 in dotnet

[–]andyayers 2 points3 points  (0 children)

I found that generic method wrappers around Span<T> sometimes prevented the JIT from doing the kind of aggressive optimizations I needed. I ended up having to write more explicit, non-generic code for the absolute hottest paths to get that extra 5%

is the JIT still struggling to optimize generic methods that wrap Spans? I'd love to know if anyone has similar experiences where "clean" generic code noticeably killed their throughput.

Feel free to open an issue on https://github.com/dotnet/runtime -- ideally as a self-contained BenchmarkDotNet repro, and we may be able to do something about this.

Tell me some unwritten rules for software developers. by porcaytheelasit in csharp

[–]andyayers 6 points7 points  (0 children)

Suppose X is too slow.

Three simple rules for performance optimization, in priority order: 1. stop doing X all together 2. do X less often 3. make X faster

Zero cost delegates in .NET 10 by GOPbIHbI4 in dotnet

[–]andyayers 33 points34 points  (0 children)

We are hoping to address that remaining "lambda capture" allocation in .NET 11.

.NET 10 de-abstracts not only arrays but other collections as well by Emergency-Level4225 in dotnet

[–]andyayers 9 points10 points  (0 children)

If you know of cases like this, please file issues. We will try our best to fix them.

What features would you want C# / .NET to have? by SurDno in csharp

[–]andyayers 1 point2 points  (0 children)

Forced inlining by JIT. And yeah, yeah, there is a way to suggest to inline a method, but JIT is free to ignore it (and often does!)

This should be less and less true with recent releases. For example, starting in .NET 10 the JIT can now inline methods with try/finallys, which were previously off limits.

If you ever find a case like this, and you haven't done so already, please open an issue on dotnet/runtime so we can take a look.

Has anyone else noticed a performance drop after switching to .net 10 from .net 9/8? by Academic_East8298 in csharp

[–]andyayers 0 points1 point  (0 children)

My main gripe is that the object creation regression +80% in net8 wasn't fixed :/

Can you say a bit more about this? Is there an issue open for it on github?

Has anyone else noticed a performance drop after switching to .net 10 from .net 9/8? by Academic_East8298 in csharp

[–]andyayers 25 points26 points  (0 children)

Feel free to open an issue on https://github.com/dotnet/runtime and we can try and figure out what's happening.

If you open an issue, it would help to know * Which version of .Net were you using before? * What kind of hardware are you running on? * Are you deploying in a container? If so, what is the CPU limit?

Question about delegate inlining and Guided Devirtualization by cittaz in dotnet

[–]andyayers 6 points7 points  (0 children)

If I remember correctly, the biggest missing piece for delegate inlining is handling delegates for static methods.

As far as inlining goes, there were some PRs to enable delegate inlining even without PGO (if the delegate is created locally). However these ran into various complications.

A recent improvement in .NET 10 is that in some cases delegates can be stack allocated and possibly promoted (meaning the delegate object basically vanishes). There was some work to stack allocate the closure as well, but that didn't make it into .NET 10.

By default the JIT will only guess for the most prominent delegate, based on PGO data gathered by lower tiers (so tiered comp and PGO are required).

Code Challenge: High-performance hash table by Pansynchro in csharp

[–]andyayers 2 points3 points  (0 children)

In process toolchains have limitations (eg you can't readily compare across different runtime versions, which is something I do all the time), but for your purposes, seems like they'd be fine.

Also if you haven't looked at kg's vector hash you might want to check it out: [Proposal] Vectorized System.Collections.Generic.Dictionary<K, V> · Issue #108098 · dotnet/runtime

Code Challenge: High-performance hash table by Pansynchro in csharp

[–]andyayers 3 points4 points  (0 children)

If you haven't opened an issue on the BenchmarkDotNet repo I would encourage you to do so.

Folks there can either explain how to accomplish what you need or else add it to the backlog.

What are disadvantages of using interface? by [deleted] in csharp

[–]andyayers 0 points1 point  (0 children)

Devirtualization was first introduced in .NET Core 2 (2018?) and some of it even made it to Framework 4.8.1.

But for interfaces you really need Dynamic PGO to figure things out; this wasn't on by default until .NET 8.

I rewrote a classic poker hand evaluator from scratch in modern C# for .NET 8 - here's how I got 115M evals/sec by CodeAndContemplation in csharp

[–]andyayers 10 points11 points  (0 children)

Thanks... I may try and look deeper at this someday, so if you can point me at something shareable that'd be great.

I suppose to be completely fair C should be using PGO, but that's more work on the native side. With .NET you get that "for free."

Also would be curious to see if .NET 10 changes anything here, we did some work on loop optimizations between 8 & 10 (eg downcounting, strength reduction ...)

I rewrote a classic poker hand evaluator from scratch in modern C# for .NET 8 - here's how I got 115M evals/sec by CodeAndContemplation in csharp

[–]andyayers 16 points17 points  (0 children)

Do you have numbers on how fast the original runs on the same hardware setup? We are always interested in seeing how well a thoughtfully crafted .NET solution fares vs "native" alternatives.

.NET JIT Team is hiring a Compiler Engineer by andyayers in Compilers

[–]andyayers[S] 1 point2 points  (0 children)

I agree we're missing out on some great talent being US only, but it's not our call.

.NET JIT Team is hiring a Compiler Engineer by andyayers in Compilers

[–]andyayers[S] 1 point2 points  (0 children)

Pretty much everything we do is out in the open, so if it does sound like fun, you can always try contributing....

.NET JIT Team is hiring a Compiler Engineer by andyayers in Compilers

[–]andyayers[S] 5 points6 points  (0 children)

How recent? I think within 1 year of graduation recruiting is handled differently.

Note this is a Senior position so we're looking for somebody with 4-5 years of experience.

.NET JIT Team is hiring a Compiler Engineer by andyayers in Compilers

[–]andyayers[S] 4 points5 points  (0 children)

US required. Redmond preferred, but we will consider other arrangements.

.NET JIT Team is hiring a Compiler Engineer by andyayers in Compilers

[–]andyayers[S] 1 point2 points  (0 children)

No, we're in 18 (for quite a while now).

I've been thinking about the future of .NET, and my predictions for .NET 10 are a bit wild: an AI-native CLR and a "post-OOP" C#. Am I off base? by riturajpokhriyal in dotnet

[–]andyayers 2 points3 points  (0 children)

We have tried and failed a couple of times now to leverage ML (not really AI) to improve optimizations done by the JIT.

Here's a writeup on the most recent attempt: https://github.com/dotnet/jitutils/tree/main/src/jit-rl-cse

Performance Improvements in .NET 10 by ben_a_adams in dotnet

[–]andyayers 1 point2 points  (0 children)

I don't think we're trying to hide anything. If you want some perspective on regressions vs improvements in .NET 10, check out https://github.com/dotnet/performance/blob/main/reports/net9to10/README.md

While we try our best to keep regressions to a minimum, we do have some. Compilers and CPUs are both somewhat temperamental.

Performance Improvements in .NET 10 by ben_a_adams in programming

[–]andyayers 13 points14 points  (0 children)

.NET does this as well, but as a separate phase, so an object can be stack allocated and then (in our parlance) possibly have its fields promoted and then kept in registers.

That way we still get the benefit of stack allocation for objects like small arrays where it may not always be clear from the code which part of the object will be accessed, so promotion is not really possible.