2013-06-06 8 views
2

나는 빠른 포인터를 사용하여 데이터의 블록을 XOR을 수행하는 코드를 가지고,하지만 난 어셈블리의 "안전하지 않은"요구 사항을 제거하고 싶습니다. 내가 변경하는 경우는 LayoutKind.Explicit을 사용하고 내가 포인터와 함께했던 같은 "ULONG []"는 "바이트 []"의 상단에, 나는 기본적으로하고있어 같은 일을 오버레이하지만, 그냥 위험한 것 같다. 이 두 가지의 주요 차이점은 "안전한"버전은 "안전하지 않은"버전의 1/2 속도입니다."안전하지 않은"포인터를 사용하여 주위를 돌아 다니려면 LayoutKind.Explicit를 사용하는 것이 합법적입니까?

이 "안전하지 않은"어셈블리를 갖는 이겨내는 합법적 인 방식으로 또는 동시에 안전한 방식으로이를 수행하는 방법을 합법적 바이트 [] 1 바이트 액세스인가?

private unsafe static void UnsafeEncode(
    byte[] buffer, int bufPos, ulong[] vector, int SectionLength, byte vectorIndex) 
{ 
    fixed (byte* p = &buffer[bufPos]) 
    { 
     ulong* pCur = (ulong*)p; 
     ulong* pEnd = pCur + SectionLength; 
     while (pCur < pEnd) 
     { 
      *pCur ^= vector[vectorIndex++]; 
      pCur++; 
     } 
    } 
} 

[StructLayout(LayoutKind.Explicit)] 
private struct ArrayOverlay 
{ 
    [FieldOffset(0)] 
    public byte[] Bytes; 
    [FieldOffset(0)] 
    public ulong[] Longs; 
} 

private static void SafeEncode(
    byte[] buffer, int bufPos, ulong[] vector, int SectionLength, byte vectorIndex) 
{ 
    var overlay = new ArrayOverlay { Bytes = buffer }; 
    int shiftleft = (bufPos & 7) << 3; 
    int pos = bufPos >> 3; 
    if (shiftleft == 0) 
    { 
     for (int i = 0; i < SectionLength; i++) 
      overlay.Longs[i + pos] ^= vector[vectorIndex++]; 
    } 
    else 
    { 
     int shiftright = (64 - shiftleft) & 63; 
     ulong oldVec = 0; 
     for (int i = 0; i < SectionLength; i++) 
     { 
      var vec = vector[vectorIndex++]; 
      overlay.Longs[i + pos] ^= (vec << shiftleft) | (oldVec >> shiftright); 
      oldVec = vec; 
     } 
     overlay.Longs[SectionLength + pos] ^= (oldVec >> shiftright); 
    } 
} 

답변

1

이것은 "안전"어셈블리를 갖는 이겨내 합법적 인 방식이며, 또는 시간에 안전한 방식으로이를 수행하는 유일한 정상적인 방식 바이트 [] 1 바이트 액세스인가?

이것은 합법적이며 1) 작동하며 2) 올바른 결과를 얻을 수 있습니다.

은 반드시 당신이 수행하여 "불쾌한"있는 일을 할 수 있다는 점에서 "안전"아니다, 부여,하지만 여전히 작동합니다. 당신은 효과적으로 우회 배열 길이 검사 및 원인 버퍼 오버런으로 "안전한"코드에서 허용되어서는 안 일을 할 수있는 당신은 확실히,이 경우 안전한 코드의 정신을 위반하고 있습니다. 한 번에 배열 한 요소를 액세스

"안전한"코드의 정신에 더 많은,하지만이 가치가 같은 트릭을 사용할 때 성능에 대한 메커니즘을 제공하기 때문에 필요한 경우가있다. 성능은 사용자의 특정 시나리오에 필요하며, 일반적인 메커니즘이 적절하게 수행하지 않을 경우,이 코드를 만들 수있는 방법이 될 수 그것이 마킹의 안전한 제약을 위반하지 않고 귀하의 사양합니다 (반환 한. 요구 사항)을 충족에 있음 "작품" 안전하지 않은 어셈블리.