.NET9 PreView6 循环优化和地址暴露

点击上方蓝字 江湖评谈设为关注/星标

608c097ee2d75db79c18cda9f42c6d8f.png

前言

本篇看下.NET9 PreView6 JIT的第二个性能优化更新,循环优化和地址暴露方面的改进。

循环优化

一般循环都是通过for来进行递增判断,如下:

for (int i = 0; i < 100; i++)
{
    Foo();
}

但是在一些其它架构上,比如Arm/Risc-V上,递减循环可能更具性能提升价值

for (int i = 100; i > 0; i--)
{
    Foo();
}

减少指令集,始终是优化的一个方向。第一个例子:

G_M35517_IG02:  ;; offset=0x0005
       xor      ebx, ebx            // Set i to 0
G_M35517_IG03:  ;; offset=0x0007
       call     [Foo()]
       inc      ebx                 // Increment i
       cmp      ebx, 100            // Compare i to 100
       jl       SHORT G_M35517_IG03 // Continue loop if (i < 100)

第二个例子

G_M35517_IG02:  ;; offset=0x0005
       mov      ebx, 100            // Set i to 100
G_M35517_IG03:  ;; offset=0x000A
       call     [Foo()]
       dec      ebx                 // Decrement i
       jne      SHORT G_M35517_IG03 // Continue loop if (i != 0)

代码的大小减少很小,但如果循环运行了大量迭代,则性能改进可能很大。RyuJIT 现在可以识别何时可以在不影响程序行为的情况下翻转循环计数器变量的方向(意即,X64上当JIT识别到不影响程序逻辑的情况下,循环递增把它改变成循环递减至0,从而减少指令单生成,提升性能),并进行转换。

地址暴露

思考一个问题,将一个方法里面的变量传递给另外一个方法,这里的变量传递过程中实际上是传递的是变量的地址。为了确保这个地址里面的值不会在传递的时候,被CLR/JIT的某个功能或者特性修改了导致出错,所以需要额外的功能做这件事情。

问题来了,这个额外的功能,会经常性的抑制一些JIT里面的优化,导致性能上不去。怎么办呢?那就是减少局部变量地址暴露的可能性。

public struct Awaitable
{
    public int Opts;


    public Awaitable(bool value)
    {
        Opts = value ? 1 : 2;
    }
}


[MethodImpl(MethodImplOptions.NoInlining)]
public static int Test() => new Awaitable(false).Opts;

x64

G_M59043_IG01:  ;; offset=0x0000
       push     rax
G_M59043_IG02:  ;; offset=0x0001
       xor      eax, eax
       mov      dword ptr [rsp], eax
       mov      dword ptr [rsp], 2   // Set Opts to 2
       mov      eax, dword ptr [rsp] // Return Opts
G_M59043_IG03:  ;; offset=0x0010
       add      rsp, 8
       ret
; Total bytes of code: 21

因为JIT实际上预先判断,已经知道了Awaitable方法的参数value为false。所以传递Opts地址时候,不需要保持其值不变。同时也避免了抑制性能的行为,即PreView6只需要赋值Opts=2即可

G_M59043_IG02:  ;; offset=0x0000
       mov      eax, 2  // Return 2
G_M59043_IG03:  ;; offset=0x0005
       ret

结尾

这两个优化与前一篇:.NET9 PreView6 RyuJIT代码布局改进(HIR) 一脉相承,都是.NET9 PreView6进行的性能改进。

往期精彩回顾

.NET9 PreView5张量和AI算力

003c3925494d2fe974d68b77d3a4a4cd.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值