Runtime: يجب أن يتعرف JIT على نمط فحص النوع الشائع

تم إنشاؤها على ٣ نوفمبر ٢٠١٨  ·  3تعليقات  ·  مصدر: dotnet/runtime

لقد وجدت الحيلة في GrabYourPitchforks https://github.com/dotnet/coreclr/pull/20386
يمكن لـ JIT التعرف على النمط وإنشاء رمز محسن للأنواع المختومة.
ج #
[MethodImpl (MethodImplOptions.NoInlining)]
int هو ثابت عام (كائن كائن)
{
إذا (obj هو سلسلة str)
طول شارع العودة ؛

        return 7;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static int As(object obj)
    {
        string str = obj as string;

        if (str != null)
            return str.Length;

        return 7;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static int SafeUnsafe(object obj)
    {
        if (obj != null && obj.GetType() == typeof(string))
            return Unsafe.As<string>(obj).Length;

        return 7;
    }
<details><summary>See the generated code</summary><p>

```ASM
; Assembly listing for method Program:Is(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
;  V00 arg0         [V00,T01] (  3,  3   )     ref  ->  rcx         class-hnd
;  V01 loc0         [V01,T02] (  3,  2.50)     ref  ->  rax         class-hnd
;# V02 OutArgs      [V02    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]  
;  V03 tmp1         [V03,T00] (  5,  6.74)     ref  ->  rax         class-hnd
;
; Lcl frame size = 0

G_M12761_IG01:
       0F1F440000           nop      

G_M12761_IG02:
       488BC1               mov      rax, rcx
       4885C0               test     rax, rax
       7411                 je       SHORT G_M12761_IG03
       48BA00F50A96FE7F0000 mov      rdx, 0x7FFE960AF500
       483910               cmp      qword ptr [rax], rdx
       7402                 je       SHORT G_M12761_IG03
       33C0                 xor      rax, rax

G_M12761_IG03:
       4885C0               test     rax, rax
       7404                 je       SHORT G_M12761_IG05
       8B4008               mov      eax, dword ptr [rax+8]

G_M12761_IG04:
       C3                   ret      

G_M12761_IG05:
       B807000000           mov      eax, 7

G_M12761_IG06:
       C3                   ret      

; Total bytes of code 45, prolog size 5 for method Program:Is(ref):int
; ============================================================


; Assembly listing for method Program:As(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
;  V00 arg0         [V00,T01] (  3,  3   )     ref  ->  rcx         class-hnd
;  V01 loc0         [V01,T02] (  3,  2.50)     ref  ->  rax         class-hnd
;# V02 OutArgs      [V02    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]  
;  V03 tmp1         [V03,T00] (  5,  6.74)     ref  ->  rax         class-hnd
;
; Lcl frame size = 0

G_M12497_IG01:
       0F1F440000           nop      

G_M12497_IG02:
       488BC1               mov      rax, rcx
       4885C0               test     rax, rax
       7411                 je       SHORT G_M12497_IG03
       48BA00F50A96FE7F0000 mov      rdx, 0x7FFE960AF500
       483910               cmp      qword ptr [rax], rdx
       7402                 je       SHORT G_M12497_IG03
       33C0                 xor      rax, rax

G_M12497_IG03:
       4885C0               test     rax, rax
       7404                 je       SHORT G_M12497_IG05
       8B4008               mov      eax, dword ptr [rax+8]

G_M12497_IG04:
       C3                   ret      

G_M12497_IG05:
       B807000000           mov      eax, 7

G_M12497_IG06:
       C3                   ret      

; Total bytes of code 45, prolog size 5 for method Program:As(ref):int
; ============================================================


; Assembly listing for method Program:SafeUnsafe(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
;  V00 arg0         [V00,T00] (  5,  4   )     ref  ->  rcx         class-hnd
;# V01 OutArgs      [V01    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]  
;
; Lcl frame size = 0

G_M6777_IG01:
       0F1F440000           nop      

G_M6777_IG02:
       4885C9               test     rcx, rcx
       7413                 je       SHORT G_M6777_IG04
       48B800F50A96FE7F0000 mov      rax, 0x7FFE960AF500
       483901               cmp      qword ptr [rcx], rax
       7504                 jne      SHORT G_M6777_IG04
       8B4108               mov      eax, dword ptr [rcx+8]

G_M6777_IG03:
       C3                   ret      

G_M6777_IG04:
       B807000000           mov      eax, 7

G_M6777_IG05:
       C3                   ret      

; Total bytes of code 35, prolog size 5 for method Program:SafeUnsafe(ref):int
; ============================================================

ولحفظ rax سيكون من الجيد أن يكون لديك

cmp      qword ptr [rcx], 0x7FFE960AF500

بدلا من

mov      rax, 0x7FFE960AF500
cmp      qword ptr [rcx], rax

التعليق الأكثر فائدة

من المفيد أن يكون لديك (وأن نتذكر) هذه الأنواع من الأمثلة.

يرجى عدم التراجع عن الإبلاغ عن الأشياء لأنك قلق بشأن الإبلاغ عن شيء معروف بالفعل. أحيانًا لا تكون الأشياء المتشابهة متشابهة في النهاية.

ال 3 كومينتر

هذا مجال معروف للتحسين (انظر dotnet / runtime # 9117).

لا تستطيع معظم تعليمات x64 التعامل مع معاملات ثابتة حرفية كبيرة ، ولهذا السبب ترى mov; cmp كما تفعل أعلاه.

أسبوع المغفلين :)
إغلاق.

من المفيد أن يكون لديك (وأن نتذكر) هذه الأنواع من الأمثلة.

يرجى عدم التراجع عن الإبلاغ عن الأشياء لأنك قلق بشأن الإبلاغ عن شيء معروف بالفعل. أحيانًا لا تكون الأشياء المتشابهة متشابهة في النهاية.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات