2012-07-16 2 views
5

코드 아래에 반영되는 형태로 닷넷 프레임 워크 : 제 생각에는Marshal.WriteInt64 메서드의 코드가 너무 복잡한 이유는 무엇입니까?

[SecurityCritical] 
public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val){ 
    try{ 
     byte* numPtr = (byte*) (((void*) ptr) + ofs); 
     if ((((int) numPtr) & 7) == 0){ 
      *((long*) numPtr) = val; 
     } 
     else{ 
      byte* numPtr2 = (byte*) &val; 
      numPtr[0] = numPtr2[0]; 
      numPtr[1] = numPtr2[1]; 
      numPtr[2] = numPtr2[2]; 
      numPtr[3] = numPtr2[3]; 
      numPtr[4] = numPtr2[4]; 
      numPtr[6] = numPtr2[6]; 
      numPtr[7] = numPtr2[7]; 
     } 
    } 
    catch (NullReferenceException){ 
     throw new AccessViolationException(); 
    } 
} 

, *((long*) numPtr) = val 충분히, 그리고 매우 효율적입니다.

왜 그렇게 복잡합니까?

+0

어쩌면 뭔가 endiens 함께 할 수있는 (이것은 '루프 언 롤링'라고합니다) 시간을 절약 할 수있는 루프를 건너 뛰고, 한 번에 한 바이트를 쓴다? . – KingCronus

+5

나에게 메모리 정렬과 관련이있는 것처럼 보입니다. –

+0

그건 memcpy()이고 손으로 풀어 놓았습니다. ARM 코어에서 필요하다고 생각합니다. –

답변

6

최적화되었지만 다소 단순합니다.

외부 참조 if - it는 Int64를 한 번의 작업으로 작성할 수 있는지 확인합니다 (메서드를 전달하는 포인터가 메모리에있는 Int64의 시작을 가리키는 경우 발생 함) - 주소는 8의 배수 여야 함). 당신은 한 번의 작업으로 쓸 수없는 경우

이 코드는

+0

그들은 4 바이트 경계에도 최적화 할 수 있다고 생각합니다. – leppie

+0

아마도 수표 자체가 너무 비싸서 평균적인 차이를 만들지 않았을 수도 있습니다. – zmbq

+0

'var data = new byte [128]; 긴 숫자 = 0x1234567890ABCDEF; 고정 (byte * p = data) { * (long *) (p + 1) = num; * (long *) (p + 10) = num; }'포인터를 정렬하지 않으면이 코드가 잘 작동합니다. – ldp