dotnet/runtime

Constant mod over chars can use a cheaper FastMod

Open

#111,492 建立於 2025年1月16日

在 GitHub 查看
 (1 留言) (4 反應) (1 負責人)C# (5,445 fork)batch import
area-CodeGen-coreclrhelp wantedin-pr

倉庫指標

Star
 (17,886 star)
PR 合併指標
 (平均合併 12天 11小時) (30 天內合併 661 個 PR)

描述

#101001 added a faster variant of FastMod that SearchValues now uses when it knows that the value and divisor are both < 2^16 (i.e. chars). Instead of https://github.com/dotnet/runtime/blob/e71d737628c7b807aa12755dabe4eca40c40da7e/src/libraries/System.Private.CoreLib/src/System/Collections/HashHelpers.cs#L107 we can use https://github.com/dotnet/runtime/blob/e71d737628c7b807aa12755dabe4eca40c40da7e/src/libraries/System.Private.CoreLib/src/System/SearchValues/ProbabilisticMapState.cs#L223


Is it worth teaching the JIT to do something similar when it knows that values are in range?

int Mod1(char c) => c % 42;
int Mod2(char c) => (int)(((ulong)(102261127u * c) * 42) >> 32);
Test.Mod1(Char)
    L0000: movzx eax, cx
    L0003: mov ecx, eax
    L0005: shr ecx, 1
    L0007: imul rcx, 0x30c30c31
    L000e: shr rcx, 0x22
    L0012: imul ecx, 0x2a
    L0015: sub eax, ecx
    L0017: ret

Test.Mod2(Char)
    L0000: movzx eax, cx
    L0003: imul eax, 0x6186187
    L0009: imul rax, 0x2a
    L000d: shr rax, 0x20
    L0011: ret

sharplab

貢獻者指南