C# SIMD 바이트 배열 비교

2337 단어 csharp
내 바이트 배열은 최근에 stackoverflow에 게시한 것과 비교됩니다.
https://stackoverflow.com/a/69280107/13843929

a1 및 a2는 전역 바이트 배열입니다. stackoverflow 게시물의 유지 관리 프로그램이 사용하고 있었고 코드의 두 복사본을 유지하고 싶지 않았기 때문에 이 방법이 수행됩니다.

stackoverflow에 대한 내 자신의 게시물을 인용...
"이것은 다른 것들과 비슷하지만 여기서 차이점은 한 번에 확인할 수 있는 다음으로 높은 바이트 수로 떨어지지 않는다는 것입니다. 예를 들어 SIMD 예에서 63바이트가 있는 경우 처음 32바이트, 다음으로 마지막 32바이트로 32바이트, 16바이트, 8바이트 등을 확인하는 것보다 빠릅니다. 입력한 첫 번째 확인은 모든 바이트를 비교하는 데 필요한 유일한 확인입니다."

내 테스트에서 가장 빠른 수행자입니다.

#requires System.Runtime.Intrinsics.X86
public unsafe bool SIMDNoFallThrough()    
{
    if (a1 == null || a2 == null)
        return false;

    int length0 = a1.Length;

    if (length0 != a2.Length) return false;

    fixed (byte* b00 = a1, b01 = a2)
    {
        byte* b0 = b00, b1 = b01, last0 = b0 + length0, last1 = b1 + length0, last32 = last0 - 31;

        if (length0 > 31)
        {
            while (b0 < last32)
            {
                if (Avx2.MoveMask(Avx2.CompareEqual(Avx.LoadVector256(b0), Avx.LoadVector256(b1))) != -1)
                    return false;
                b0 += 32;
                b1 += 32;
            }
            return Avx2.MoveMask(Avx2.CompareEqual(Avx.LoadVector256(last0 - 32), Avx.LoadVector256(last1 - 32))) == -1;
        }

        if (length0 > 15)
        {
            if (Sse2.MoveMask(Sse2.CompareEqual(Sse2.LoadVector128(b0), Sse2.LoadVector128(b1))) != 65535)
                return false;
            return Sse2.MoveMask(Sse2.CompareEqual(Sse2.LoadVector128(last0 - 16), Sse2.LoadVector128(last1 - 16))) == 65535;
        }

        if (length0 > 7)
        {
            if (*(ulong*)b0 != *(ulong*)b1)
                return false;
            return *(ulong*)(last0 - 8) == *(ulong*)(last1 - 8);
        }

        if (length0 > 3)
        {
            if (*(uint*)b0 != *(uint*)b1)
                return false;
            return *(uint*)(last0 - 4) == *(uint*)(last1 - 4);
        }

        if (length0 > 1)
        {
            if (*(ushort*)b0 != *(ushort*)b1)
                return false;
            return *(ushort*)(last0 - 2) == *(ushort*)(last1 - 2);
        }

        return *b0 == *b1;
    }
}

좋은 웹페이지 즐겨찾기