Wat is er nieuw in de runtime van .NET 11

In dit artikel worden nieuwe functies in de .NET runtime voor .NET 11 beschreven. Het is voor het laatst bijgewerkt voor Preview 6.

Minimale hardwarevereisten bijgewerkt

De minimale hardwarevereisten voor .NET 11 zijn bijgewerkt om modernere instructiesets te vereisen voor zowel x86/x64- als Arm64-architecturen. Daarnaast zijn de ReadyToRun -compilatiedoelen (R2R) bijgewerkt om te profiteren van nieuwere hardwaremogelijkheden.

Arm64-vereisten

Voor Apple is er geen wijziging in de minimale hardware of het ReadyToRun-doel. De Apple M1-chips zijn ongeveer gelijk aan armv8.5-a en bieden ondersteuning voor ten minste de AdvSimd (NEON), CRC, DOTPROD, LSE, RCPC, , en RCPC2RDMA instructiesets.

Voor Linux is er geen wijziging in de minimale hardware. .NET blijft apparaten zoals Raspberry Pi ondersteunen die mogelijk alleen ondersteuning bieden voor de instructieset AdvSimd. Het ReadyToRun-doel is bijgewerkt om de LSE instructieset op te nemen, wat kan leiden tot extra jitting-overhead als u een toepassing start.

Voor Windows wordt de basiskavel bijgewerkt zodat het de instructieset LSE vereist. Dit is vereist door Windows 11 en door alle Arm64-CPU's die officieel worden ondersteund door Windows 10. Daarnaast is het in overeenstemming met de vereisten voor Arm SBSA (Server Base System Architecture). Het ReadyToRun-doel is bijgewerkt naar armv8.2-a + RCPC, dat ondersteuning biedt voor ten minste AdvSimd, CRC, LSE, RCPC en RDMA en het merendeel van de officieel ondersteunde hardware dekt.

OS Vorige JIT/AOT-minimum Nieuwe minimum JIT/AOT Vorige R2R-doel Nieuw R2R-doel
Appel Apple M1 (Geen wijziging) Apple M1 (Geen wijziging)
Linux armv8.0-a (Geen wijziging) armv8.0-a armv8.0-a + LSE
Windows armv8.0-a armv8.0-a + LSE armv8.0-a armv8.2-a + RCPC

x86/x64-vereisten

Voor alle drie de besturingssystemen (Apple, Linux en Windows) wordt de basislijn bijgewerkt van x86-64-v1 naar x86-64-v2. Hierdoor garandeert de hardware niet alleen CMOV, CX8, SSE, en SSE2, maar ook CX16, POPCNT, SSE3, SSSE3, SSE4.1, en SSE4.2. Deze garantie is vereist voor Windows 11 en door alle x86/x64 CPU's die officieel worden ondersteund op Windows 10. Het omvat alle chips die nog steeds officieel worden ondersteund door Intel en AMD, met de laatste oudere chips die rond 2013 uit de ondersteuning zijn gegaan.

Het ReadyToRun-doel is bijgewerkt naar x86-64-v3 voor Windows en Linux, die bovendien de AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT en MOVBE instructiesets omvat. Het ReadyToRun-doel voor Apple blijft ongewijzigd.

OS Vorige JIT/AOT-minimum Nieuwe minimum JIT/AOT Vorige R2R-doel Nieuw R2R-doel
Appel x86-64-v1 x86-64-v2 x86-64-v2 (Geen wijziging)
Linux x86-64-v1 x86-64-v2 x86-64-v2 x86-64-v3
Windows x86-64-v1 x86-64-v2 x86-64-v2 x86-64-v3

Impact

Vanaf .NET 11 kan .NET niet worden uitgevoerd op oudere hardware en kan er een bericht worden afgedrukt dat vergelijkbaar is met het volgende:

De huidige CPU ontbreekt een of meer van de basislijninstructiesets.

Voor ReadyToRun-compatibele assembly's is er mogelijk extra opstartoverhead op sommige ondersteunde hardware die niet voldoet aan de verwachte ondersteuning voor een typisch apparaat.

Reden voor wijziging

.NET ondersteunt een breed scala aan hardware, vaak boven en buiten de minimale hardwarevereisten die worden ingevoerd door het onderliggende besturingssysteem. Deze ondersteuning voegt aanzienlijke complexiteit toe aan de codebasis, met name voor veelal oudere hardware die waarschijnlijk niet meer in gebruik is. Daarnaast definieert het een 'laagste algemene noemer' waarnaar AOT-doelen standaard moeten worden ingesteld, wat in sommige scenario's kan leiden tot verminderde prestaties.

De update naar de minimale basislijn is gemaakt om de onderhoudscomplexiteit van de codebasis te verminderen en om beter af te stemmen op de gedocumenteerde (en vaak afgedwongen) hardwarevereisten van het onderliggende besturingssysteem.

Zie Minimale hardwarevereisten bijgewerkt voor meer informatie.

Runtime Async

.NET 11 introduceert runtimeeigen asynchroon (Runtime Async V2), een belangrijke stap voor het vervangen van door compiler gegenereerde asynchrone asynchrone machines met runtime beheerde schorsing en hervatting. In plaats van dat de compiler toestandsmachinemodellen genereert, houdt de runtime zelf de asynchrone uitvoering bij, wat leidt tot schonere stack traces, betere debugbaarheid en lagere overhead.

Runtime Async is een preview-functie. Als u zich wilt aanmelden, voegt u de volgende eigenschap toe aan uw projectbestand:

<PropertyGroup>
  <Features>runtime-async=on</Features>
</PropertyGroup>

Een net11.0 project hoeft <EnablePreviewFeatures>true</EnablePreviewFeatures> geen Runtime Async meer te gebruiken.

De .NET runtimebibliotheken zelf worden gecompileerd met runtime-async=on. De runtimebibliotheken bevatten niet langer door de compiler gegenereerde toestandsmachines en zijn volledig afhankelijk van door de runtime geboden async. Dit maakt het mogelijk om een hele app (met alleen bibliotheekafhankelijkheden) te migreren naar het nieuwe model en biedt uitgebreide functionele en prestatievalidatie van de functie. Het productteam verwelkomt alle rapporten (positief of negatief) over wijzigingen in doorvoer en bibliotheekgrootte die u ziet.

.NET 11 bevat ook twee extra verbeteringen:

  • Covariante TaskTask<T> overschrijvingen: Wanneer een afgeleide klasse Task<T> retourneert voor een basismethode die Task retourneert, genereert de runtime nu een thunk met void-retourtype die het verschil in aanroepconventie overbrugt, zodat virtuele dispatch voor beide varianten werkt. Dezelfde oplossing is van toepassing op NativeAOT.
  • Inlining in crossgen2: Beperkingen waardoor runtime-asynchrone methoden niet inline worden opgenomen tijdens de compilatie ReadyToRun (R2R) zijn verwijderd. Alle asynchrone tests slagen met zowel crossgen2 als composite-R2R, en het inline plaatsen van async-aanroepen zonder await (het synchrone snelle pad) is van begin tot eind bevestigd.

Opmerking

De DOTNET_RuntimeAsync variabelen en UNSUPPORTED_RuntimeAsync omgevingsvariabelen die eerder runtime-asynchroon gedrag hebben beheerd, zijn verwijderd. Als u runtime-async per project wilt uitschakelen, stelt u <UseRuntimeAsync>false</UseRuntimeAsync> in in uw projectbestand, in plaats van de omgevingsvariabele te gebruiken.

Schonere live stacktraceringen

De meest zichtbare verbetering is in livestacktraceringen: wat profilers, foutopsporingsprogramma's en new StackTrace() zien tijdens de uitvoering. Bij door de compiler gegenereerde asynchrone methoden produceert elke asynchrone methode meerdere frames vanuit de toestandsmachine-infrastructuur. Met Runtime Async worden de werkelijke methoden rechtstreeks op de aanroepstack weergegeven.

// To enable runtime async, add the following to your .csproj:
//   <Features>runtime-async=on</Features>

await OuterAsync();

static async Task OuterAsync()
{
    await Task.CompletedTask;
    await MiddleAsync();
}

static async Task MiddleAsync()
{
    await Task.CompletedTask;
    await InnerAsync();
}

static async Task InnerAsync()
{
    await Task.CompletedTask;
    Console.WriteLine(new StackTrace(fNeedFileInfo: true));
}

Zonder runtime-async—13 frames, infrastructuur voor statuscomputers zichtbaar:

   at Program.<<Main>$>g__InnerAsync|0_2() in Program.cs:line 24
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
   at Program.<<Main>$>g__InnerAsync|0_2()
   at Program.<<Main>$>g__MiddleAsync|0_1() in Program.cs:line 14
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
   at Program.<<Main>$>g__MiddleAsync|0_1()
   at Program.<<Main>$>g__OuterAsync|0_0() in Program.cs:line 8
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
   at Program.<<Main>$>g__OuterAsync|0_0()
   at Program.<Main>$(String[] args) in Program.cs:line 3
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
   at Program.<Main>$(String[] args)
   at Program.<Main>(String[] args)

Met runtime-async—5 frames, de echte oproepketen:

   at Program.<<Main>$>g__InnerAsync|0_2() in Program.cs:line 24
   at Program.<<Main>$>g__MiddleAsync|0_1() in Program.cs:line 14
   at Program.<<Main>$>g__OuterAsync|0_0() in Program.cs:line 8
   at Program.<Main>$(String[] args) in Program.cs:line 3
   at Program.<Main>(String[] args)

Opmerking

Uitzonderingsstacktraceringen (van catch (Exception ex)) zien er al hetzelfde uit met of zonder Runtime Async, omdat bestaande ExceptionDispatchInfo opschoning in door compiler gegenereerde code dat geval afhandelt. De verbetering ligt in wat u ziet tijdens live uitvoering.

Deze verbetering biedt voordelen voor alles wat de liveuitvoeringsstack inspecteert, waaronder profileringsprogramma's, diagnostische logboekregistratie en het aanroepstackvenster voor foutopsporingsprogramma's.

NativeAOT- en ReadyToRun-ondersteuning

Runtime Async ondersteunt NativeAOT en ReadyToRun-compilatie. Dit breidt de functie uit buiten JIT-gecompileerde code naar scenario's die vooraf zijn gecompileerd. De runtime hergebruikt continuatie-objecten intensiever en vermijdt het opslaan van ongewijzigde lokale variabelen, waardoor de toewijzingsdruk in code met veel async-activiteiten wordt verminderd.

Verbeteringen voor foutopsporing

Onderbrekingspunten zijn nu correct gebonden binnen asynchrone runtime-methoden en het foutopsporingsprogramma kan grenzen van await doorstappen zonder naar infrastructuur gegenereerd door de compiler te springen.

Prestatieverbeteringen van Runtime Async

Preview 6 voegt verschillende prestatieverbeteringen toe aan Runtime Async:

  • Asynchrone JIT-ondersteuning: De JIT compileert een specifieke runtime-asynchrone versie van een synchrone methode die een taak retourneert, in plaats van via een thunk te delegeren. De JIT zet de staartaanroepen van de methode om in asynchrone runtime-aanroepen en wacht vervolgens op de taak die anders zou worden geretourneerd, waardoor een extra niveau van indirectie wordt geëlimineerd.
  • Samengevoegde opschortingspunten aan het einde: De JIT voegt asynchrone opschortingspunten aan het einde samen, zodat de gegenereerde code kleiner wordt.
  • In de cache opgeslagen continuaties: Continuaties die worden gebruikt voor asynchrone, tijdens runtime aanroepbare taakthunks, worden in de cache opgeslagen en hergebruikt.
  • Gepoolde methoden uitgezonderd: Methoden die al gepoold zijn, worden uitgesloten van runtime-async, zodat dubbel werk wordt voorkomen.

Asynchrone vervolgtaken zonder ExecutionContext

Asynchrone voortzettingen kunnen nu afzien van het opslaan en terugzetten van ExecutionContext. ExecutionContext draagt contextstatus — zoals AsyncLocal<T>-waarden — over await-punten heen. Elke Task voortzetting heeft eerder een momentopname van de context vastgelegd en hersteld voordat deze werd uitgevoerd, zelfs wanneer er geen AsyncLocal<T> status werd gebruikt en de herstelbewerking een no-opwas.

De runtime detecteert nu wanneer een continuatie niets te herstellen heeft en slaat de capture-/restorecyclus dan volledig over. Task, Task<T>, ValueTask en ValueTask<T> profiteren allemaal van deze wijziging, net als het runtime-async-implementatiepad. Toepassingen die ConfigureAwait(false) en AsyncLocal<T> spaarzaam gebruiken, zien minder overhead in asynchrone codepaden met hoge doorvoer.

JIT-verbeteringen

  • Verwijdering van grenzencontrole: De Just-In-Time-compiler (JIT) elimineert nu grenzencontrole voor het algemene patroon waarbij een index plus een constante wordt vergeleken met een lengte, zoals i + cns < len. Het elimineert ook meer redundante grenzencontroles voor index-from-end-toegang (bijvoorbeeld values[^1]). Deze verbeteringen verminderen redundante controles in strakke lussen en verbeteren de doorvoer voor matrix- en spanbewerkingen.
  • Verwijderen van redundante gecontroleerde contexten: De JIT kan nu redundante, gecontroleerde rekenkundige contexten herkennen en verwijderen, bijvoorbeeld wanneer een waarde al binnen het bereik valt. Deze optimalisatie elimineert onnodige overloopcontroles in gegenereerde code.
  • Vouwen van expressies: Expressies met meerdere doelen worden nu samengevouwen tot eenvoudigere controles zonder vertakkingen wanneer de doelen een kleine set constanten zijn, bijvoorbeeld switch.
  • Snellere uint-to-float/double casts: Het casten van uint naar float of double is sneller op pre-AVX-512 x86 hardware.
  • Devirtualisatie in ReadyToRun-installatiekopieën: ReadyToRun-installatiekopieën (R2R) kunnen nu niet-gedeelde algemene virtuele methodeaanroepen devirtualiseren, waardoor de prestaties van vooraf gecompileerde code voor algemene scenario's worden verbeterd.
  • SVE2-intrinsieke kenmerken: Nieuwe arm-SVE2 (Scalable Vector Extension 2) intrinsieken zijn beschikbaar: ShiftRightLogicalNarrowingSaturate(Even|Odd). Hiermee wordt de set gevectoriseerde bewerkingen uitgebreid, beschikbaar op Arm-hardware die SVE2 ondersteunt.
  • Math.BigMul op x64:Math.BigMul(long, long, out long) is nu aanzienlijk sneller op x64. De JIT genereert één MUL r/m64 instructie wanneer beide operanden 64-bits waarden zijn en de beller de hoge helft van het resultaat aanvraagt, waardoor de vorige helperoproep wordt geëlimineerd.
  • Single-IG beperking voor prolog verwijderd: Het JIT vereist niet langer dat de functie prolog in één instructiegroep (IG) past. Complexe prologen met veel opgeslagen registers, grote stackallocaties of het opzetten van runtime-async-status triggeren niet langer fallbackpaden.
  • SELECT(cond, cns, cns) vouwen: De JIT vereenvoudigt nu conditionele selecties waarvan beide vertakkingen dezelfde constante produceren tot die constante; condition ? 42 : 42 wordt bijvoorbeeld 42. Deze optimalisatie elimineert onnodige vergelijkingen die kunnen ontstaan nadat eerdere optimalisaties takken hebben samengevoegd.
  • ARM64 Vector<T> op basis van referentie voor SVE: wanneer de runtime wordt gecompileerd met ARM SVE-ondersteuning, Vector<T> worden waarden doorgegeven door verwijzing in plaats van op waarde, in overeenstemming met de ARM-aanroepconventie voor schaalbare typen en het inschakelen van betere codegeneratie voor SVE-intensieve code.

Voor betere prestaties en codekwaliteit voegt .NET 11 nog enkele JIT-optimalisaties toe:

SequenceEqual voor constantexpressies vereenvoudigen

De JIT kan nu een string.Equals- of ReadOnlySpan<T>.SequenceEqual-aanroep samenvoegen waarbij beide operanden compile-time-constanten zijn, waarbij de byte-voor-bytevergelijking wordt vervangen door het constante resultaat true of false. Dit is het belangrijkst na het inlijnen, wanneer een aanroeper een andere letterlijke waarde doorgeeft aan een helper die vergelijkt met een bekende tekenreeks. Wanneer IsAdmin wordt geïnline'd in een aanroeper die "Guest" doorgeeft, ziet de JIT "Guest" == "Admin" en vereenvoudigt dit tot false:

static bool IsAdmin(string role) => role == "Admin";

De optimalisatie is van toepassing op letterlijke tekenreeksen, const string velden en UTF-8 letterlijke waarden (bijvoorbeeld "PNG"u8).

Bereikcontroles elimineren na een controle op een lege span

De JIT neemt nu de length != 0-assertie over uit een controle op een lege span en gebruikt die om te bewijzen dat de grenscontrole voor het eerste element slaagt:

if (!span.IsEmpty && span[0] == value)
{
    // The bounds check on span[0] is now eliminated.
}

Eliminatie van overbodige vertakkingen en tests

Wanneer een extern predicaat al besloten ligt in een interne vertakking, verwijdert de JIT nu de redundante externe controle. Als code een waarde in een voorwaardelijk toewijst en deze vervolgens onmiddellijk test, wordt de tweede test geëlimineerd:

if (x > 0)
{
    if (x > 1) S();  // The outer x > 0 check is folded away.
}

int y = condition ? 1 : 2;
if (y == 1) A(); else B();  // The y == 1 test is eliminated;
                             // each branch of the ternary goes directly to A() or B().

Deze optimalisaties zijn het meest zichtbaar na inlining, waarbij bewakers van verschillende methoden in dezelfde gecompileerde hoofdtekst terechtkomen.

Hardware-intrinsieke kenmerken en codegeneratie

.NET 11 bevat verschillende nieuwe hardware-intrinsieken en verbeteringen voor het genereren van code:

  • F16C-versnelling voor Halffloat conversies op x64: Wanneer de CPU F16C (de meeste AVX2-compatibele hardware) ondersteunt, gebruiken conversies tussen Half en float/double nu de speciale vcvtph2ps/vcvtps2ph instructies in plaats van hulpaanroepen.
  • Betere kostenmodellering voor x86/x64 SIMD: De kosten van de JIT voor floating-point-uitvoering en codegrootte weerspiegelden voorheen aannames uit het x87-tijdperk. Bijgewerkte kostenmodellen die de moderne SSE/AVX-hardware weerspiegelen, stellen de JIT in staat betere beslissingen te nemen over het verplaatsen van code en de eliminatie van gemeenschappelijke subexpressies (CSE) rond SIMD-code.
  • Sneller DotProduct op AVX: Het omzetten van Vector128.Dot-achtige bewerkingen genereert nu een mul + permute + add-reeks in plaats van vdpps/vdppd wanneer AVX beschikbaar is, wat consequent sneller is.
  • Sneller IndexOfAnyAsciiSearcher op Arm64: Arm64-versies van Vector*.Count, IndexOf en LastIndexOf lopen niet langer via ExtractMostSignificantBits, wat een prestatieverbetering van 5–50% oplevert voor workloads die deze API's in hun hoofdlus gebruiken.
  • Arm64 ToScalar voor 64-bits gehele getallen:ToScalar aan Vector*<long> en Vector*<ulong> gebruikt nu fmov in plaats van umov, wat korter en sneller is op de meeste kernen.
  • SVE CreateWhile API-uitbreiding:CreateWhile krijgt ondertekende, doubleen single varianten naast de bestaande niet-ondertekende varianten, waarbij het predicaatgeneratieoppervlak voor SVE-lussen wordt voltooid.
  • Nieuwe SVE2- en Arm64-instructiesetdetectie: De runtime rapporteert SVE_AESnu , SVE_SHA3, SVE_SM4en SHA3SM4 als afzonderlijke instructiesets, waardoor query's voor deze functies op compatibele hardware worden toegestaanSve2*.IsSupported.
  • Oplossing voor AVX10-detectie: De cache van CPUID-bits voor AVX10 werd overschreven door een latere aanvraag, wat ertoe kon leiden dat AVX10 op geschikte hardware onjuist werd gerapporteerd. Dit is nu opgelost.

ReadyToRun-verbeteringen

Comparer<T>.Default en EqualityComparer<T>.Default zijn nu gespecialiseerd in ReadyToRun-images (R2R). Voorheen gebruikten de standaardvergelijkers reflectie die R2R niet vooraf kon voorzien, waardoor aanroepers op de JIT moesten terugvallen. R2R genereert nu een gespecialiseerde helper in de afbeelding, waarbij de NativeAOT-benadering wordt gespiegeld en benchmarks worden weergegeven tot een verbetering van 20× voor verzamelingenbewerkingen die afhankelijk zijn van de standaardvergelijker.

VM-verbeteringen

  • Interfaceverzending in cache op niet-JIT-platforms: Op platforms die geen JIT-ondersteuning hebben, zoals iOS, viel de interface-verzending terug op een duur algemeen fixuppad. Verzending in cache levert tot 200x verbeteringen op in interface-zware code op deze doelen.
  • Guid.NewGuid() op Linux:Guid.NewGuid() in Linux wordt nu de getrandom() syscall gebruikt met batchcaching in plaats van te lezen van /dev/urandom, wat ongeveer 12% doorvoerverbetering oplevert voor guid-generatie.

WebAssembly-verbeteringen

Browser- en WebAssembly-ondersteuning heeft verschillende verbeteringen:

  • Laden van webCIL-nettolading: De runtime kan nu webCIL-nettoladingen rechtstreeks laden, waardoor de compatibiliteit met implementatiescenario's in de browser wordt verbeterd.
  • Opsporingssymbolen: Symbool- en stacktraceringskwaliteit voor WebAssembly-foutopsporing is verbeterd, waardoor het eenvoudiger is om problemen in door de browser gehoste .NET-apps vast te stellen.
  • float[], Span<float>, en ArraySegment<float> marshaling:float[], Span<float>, en ArraySegment<float> worden nu meer rechtstreeks gemarshaled over JavaScript-grenzen, waardoor de overhead voor interop-zware code wordt verminderd.

.NET bevat verbeteringen in CoreCLR-on-WebAssembly:

  • WebCIL V1 is de standaardinstelling voor CoreCLR WASM-builds: De gedeelde WebCIL-header krijgt een TableBase veld (28 → 32 bytes). Zowel Mono- als CoreCLR-lezers accepteren V0 en V1. Crossgen2s WasmObjectWriter produceert V1 rechtstreeks en CoreCLR-varianten van de WASM SDK-builds stellen WasmWebcilVersion standaard in op V1.
  • Systeemeigen herkoppeling werkt voor CoreCLR WASM-apps: Een volledige Emscripten-pijplijn vervangt de vorige stub-doelen. Het opnieuw linken van dotnet.native.wasm uit het runtimepakket en het opnemen van aangepaste native code via NativeFileReference werkt nu.
  • JavaScript-minificatie in Release-builds: Browser CoreCLR Release-builds bevatten geminimaliseerde JavaScript.
  • NativeAOT-publicatie voor WASM laat pakketsatellieten niet langer weg: Satellietassemblies van NuGet-pakketten worden nu doorgegeven aan ILC en uit de publicatie-uitvoer weggesnoeid, waardoor lokalisatie wordt hersteld voor met AOT gepubliceerde apps die afhankelijk zijn van pakketten zoals System.CommandLine.

Platformondersteuning voor meer dan 1024 CPU's

De .NET runtime kan nu worden geïnitialiseerd op computers met meer dan 1024 logische processors. Voorheen werd sched_getaffinity aangeroepen met de standaardwaarde cpu_set_t (beperkt tot 1024), waardoor initialisatie mislukt op servers met een hoog kernaantal. De runtime wijst nu dynamisch de CPU-set toe. De GC behoudt de limiet van 1024-heap, maar de limiet voor het AANTAL CPU's wordt verwijderd.

Interne registratie van crashrapporten

Met een nieuw in-process crashrapportagemechanisme worden diagnostische gegevens vastgelegd vanuit het crashproces voordat het wordt beëindigd. Voorheen werden crashdiagnostische gegevens verzameld door een out-of-process-monitor. Hoewel de out-of-process-benadering veilig is, kan er informatie worden gemist die alleen beschikbaar is binnen het proces dat op het punt staat te worden beëindigd. Het nieuwe in-process-pad legt de beheerde stacktrace, de modulelijst en de belangrijkste runtimestatus vast op een algemeen bekend pad voordat het proces wordt beëindigd.

Deze mogelijkheid is specifiek voor mobiele platforms.

NativeAOT: snellere interface-verzending

NativeAOT maakt nu gebruik van een dispatch-helper voor interfacemethode-aanroepen. In plaats van een directe fat-pointer-aanroepreeks leidt de runtime interface-dispatch via een gedeelde helper die naar de juiste implementatie kan worden gepatcht nadat de aanroeplocatie voldoende vaak is gebruikt. Dit vermindert de binaire grootte van sites voor interface-aanroepen en verbetert de doorvoer voor workloads met veel interfacemethode-aanroepen.

SIMD lane opbouw en samenstelling

System.Runtime.Intrinsics omvat nu baanconstructie- en samenstelling-API's voor hardwarevectortypen. Met de nieuwe API's kunt u een vector maken op basis van individueel opgegeven banen en banen tussen vectoren extraheren of opnieuw ordenen. Dit maakt nauwkeurige, draagbare controle over de plaatsing van SIMD-vectorelementen mogelijk zonder terug te vallen op platformspecifieke intrinsieke elementen.

De nieuwe methoden vallen in een aantal families:

  • Gepatroonte constructie:CreateGeometricSequence, CreateAlternatingSequenceen CreateHarmonicSequence bouw een vector op basis van een beginwaarde en een regel.
  • Interleave en de-interleave:Zip, ZipLower/ZipUpper, Unzip, UnzipEven/UnzipOdd.
  • Herschikken: De Concat familie (ConcatLowerLower, ConcatLowerUpper, ConcatUpperLower, ConcatUpperUpper) en Reverse.
using System.Runtime.Intrinsics;

// {1, 2, 4, 8} — each lane is the previous lane times two
Vector128<int> powers = Vector128.CreateGeometricSequence(1, 2);

// Interleave two vectors lane-by-lane
(Vector128<int> lower, Vector128<int> upper) =
    Vector128.Zip(Vector128.Create(1), Vector128.Create(2));

Deze API's zijn beschikbaar op Vector128<T>, Vector256<T>, Vector512<T>en Vector64<T>Vector<T>. Ze zijn bouwstenen voor beeldverwerking, audio digitale signaalverwerking (DSP) en andere SIMD-intensieve werkbelastingen die nauwkeurige controle over de indeling van vectorelementen nodig hebben.

Zie ook