2012-07-16 35 views
5

Mã mẫu dưới đây được được phản ánh .Net Framework:Tại sao mã của phương thức Marshal.WriteInt64 quá phức tạp?

[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(); 
    } 
} 

Theo tôi, *((long*) numPtr) = val là đủ, và rất hiệu quả.

Tại sao quá phức tạp?

+0

Có lẽ một cái gì đó để làm với endiens? . – KingCronus

+5

Trông giống như nó liên quan đến bộ nhớ liên kết với tôi. –

+0

Đó là memcpy(), không được kiểm soát bằng tay. Cần thiết trên lõi ARM, tôi nghĩ vậy. –

Trả lời

6

Có vẻ như khá đơn giản, mặc dù được tối ưu hóa.

Lưu ý bên ngoài nếu - nó kiểm tra xem bạn có thể viết Int64 trong một thao tác hay không (điều đó xảy ra nếu con trỏ bạn đưa phương pháp được căn chỉnh đúng - điểm vào đầu Int64 trong bộ nhớ - địa chỉ cần là bội số của 8).

Nếu bạn không thể viết trong một hoạt động, mã chỉ viết một byte tại một thời điểm, bỏ qua vòng lặp để tiết kiệm thời gian (điều này được gọi là 'vòng unrolling')

+0

Đoán rằng họ có thể đã tối ưu hóa nó cho 4 byte ranh giới quá. – leppie

+0

Có thể, mặc dù bản thân séc có thể quá đắt để tạo ra sự chênh lệch thực sự trung bình. – zmbq

+0

'var data = new byte [128]; long num = 0x1234567890ABCDEF; cố định (byte * p = dữ liệu) { * (dài *) (p +1) = num; * (dài *) (p + 10) = num; } 'Nếu không có con trỏ liên kết, mã này hoạt động tốt. – ldp

Các vấn đề liên quan