Re[15]: А чего молчим про Crowdstrike
От: rameel https://github.com/rsdn/CodeJam
Дата: 26.07.24 01:44
Оценка: +2 :)
Здравствуйте, vdimas, Вы писали:

V>И это не самый эффективный способ итерации по массивам и вообще по данным — не зря сейчас рекомендуют получать Span, и итерироваться уже по нему.


Вся разница итерации по массиву и span — это учет дополнительного смещения при считывании адреса элемента для случая с массивами, в span этого нет, потому что там уже сделана поправка на это.

add eax, [rdx+r10*4]

; vs

add eax, [rcx+r10*4+0x10]
                   ^^^^^


А с учетом оптимизации JIT: Enable strength reduction by default, в .NET 9 теперь разницы уже нет никакой.

Где для случая

    public static int Sum_Array(int[] data)
    {
        var r = 0;
        foreach (var v in data)
            r += v;
        return r;        
    }

    public static int Sum_Span(Span<int> data)
    {
        var r = 0;
        foreach (var v in data)
            r += v;
        return r;        
    }


JIT приводит код в такое представление:

    public static int Sum_Array_Optimized(int[] data)
    {
        var r = 0;

        var count = data.Length;
        if (count > 0)
        {
            ref var p = ref MemoryMarshal.GetArrayDataReference(data);
        
            for (; count != 0; p = ref Unsafe.Add(ref p, 1), count--)
                r += p;
        }
        
        return r;
    }
    
    public static int Sum_Span_Optimized(Span<int> data)
    {
        var r = 0;
        
        ref var p = ref MemoryMarshal.GetReference(data);
        var count = data.Length;
        
        for (; count != 0; p = ref Unsafe.Add(ref p, 1), count--)
            r += p;
        
        return r;
    }


И получаем идентичный выхлоп для всех 4 случаев

Sample:Sum_Array(int[]):int
G_M000_IG01:                ;; offset=0x0000
 
G_M000_IG02:                ;; offset=0x0000
       xor      eax, eax
       mov      edx, dword ptr [rcx+0x08]
       test     edx, edx
       jle      SHORT G_M000_IG05
 
G_M000_IG03:                ;; offset=0x0009
       add      rcx, 16
       align    [0 bytes for IG04]
 
G_M000_IG04:                ;; offset=0x000D
       add      eax, dword ptr [rcx]
       add      rcx, 4
       dec      edx
       jne      SHORT G_M000_IG04
 
G_M000_IG05:                ;; offset=0x0017
       ret      
 
; Total bytes of code 24
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.