5

EDITChế độ xem tháo gỡ của mã phát hành C# 64 bit là dài hơn 75% so với mã gỡ lỗi 32 bit?

Tôi đã thử nghiệm bản phát hành ở 32 bit và mã nhỏ gọn. Vì vậy dưới đây là một vấn đề 64 bit.


Tôi đang sử dụng RC 2012 RC. Gỡ lỗi là 32 bit và Bản phát hành là 64 bit. Dưới đây là gỡ lỗi sau đó giải phóng tháo gỡ một dòng mã:

  crc = (crc >> 8)^crcTable[((val & 0x0000ff00) >> 8)^crc & 0xff]; 
0000006f mov   eax,dword ptr [ebp-40h] 
00000072 shr   eax,8 
00000075 mov   edx,dword ptr [ebp-3Ch] 
00000078 mov   ecx,0FF00h 
0000007d and   edx,ecx 
0000007f shr   edx,8 
00000082 mov   ecx,dword ptr [ebp-40h] 
00000085 mov   ebx,0FFh 
0000008a and   ecx,ebx 
0000008c xor   edx,ecx 
0000008e mov   ecx,dword ptr ds:[03387F38h] 
00000094 cmp   edx,dword ptr [ecx+4] 
00000097 jb   0000009E 
00000099 call  6F54F5EC 
0000009e xor   eax,dword ptr [ecx+edx*4+8] 
000000a2 mov   dword ptr [ebp-40h],eax 
----------------------------------------------------------------------------- 
     crc = (crc >> 8)^crcTable[((val & 0x0000ff00) >> 8)^crc & 0xff]; 
000000a5 mov   eax,dword ptr [rsp+20h] 
000000a9 shr   eax,8 
000000ac mov   dword ptr [rsp+38h],eax 
000000b0 mov   rdx,124DEE68h 
000000ba mov   rdx,qword ptr [rdx] 
000000bd mov   eax,dword ptr [rsp+00000090h] 
000000c4 and   eax,0FF00h 
000000c9 shr   eax,8 
000000cc mov   ecx,dword ptr [rsp+20h] 
000000d0 and   ecx,0FFh 
000000d6 xor   eax,ecx 
000000d8 mov   ecx,eax 
000000da mov   qword ptr [rsp+40h],rdx 
000000df mov   rax,qword ptr [rsp+40h] 
000000e4 mov   rax,qword ptr [rax+8] 
000000e8 mov   qword ptr [rsp+48h],rcx 
000000ed cmp   qword ptr [rsp+48h],rax 
000000f2 jae   0000000000000100 
000000f4 mov   rax,qword ptr [rsp+48h] 
000000f9 mov   qword ptr [rsp+48h],rax 
000000fe jmp   0000000000000105 
00000100 call  000000005FA5D364 
00000105 mov   rax,qword ptr [rsp+40h] 
0000010a mov   rcx,qword ptr [rsp+48h] 
0000010f mov   ecx,dword ptr [rax+rcx*4+10h] 
00000113 mov   eax,dword ptr [rsp+38h] 
00000117 xor   eax,ecx 
00000119 mov   dword ptr [rsp+20h],eax 

Tất cả mã bổ sung trong phiên bản 64 bit là gì? Nó đang thử nghiệm cái gì? Tôi đã không benchmarked này, nhưng mã 32 bit nên thực hiện nhanh hơn nhiều.

EDIT

Toàn bộ chức năng:

public static uint CRC32(uint val) 
{ 
    uint crc = 0xffffffff; 

    crc = (crc >> 8)^crcTable[(val & 0x000000ff)^crc & 0xff]; 
    crc = (crc >> 8)^crcTable[((val & 0x0000ff00) >> 8)^crc & 0xff]; 
    crc = (crc >> 8)^crcTable[((val & 0x00ff0000) >> 16)^crc & 0xff]; 
    crc = (crc >> 8)^crcTable[(val >> 24)^crc & 0xff]; 

    // flip bits 
    return (crc^0xffffffff); 
} 
+0

Nó sẽ giúp xem toàn bộ chức năng, không chỉ là một dòng của nó. –

+3

Cố gắng so sánh các khác biệt khi được xây dựng để gỡ lỗi và bản phát hành khác không hợp lệ. So sánh ít nhất cùng một loài (debug/debug hoặc release/release). –

+0

@KenWhite Tôi đồng ý. Nhưng đó là một thực tế rằng gỡ lỗi là nhỏ gọn hơn mà thu hút sự chú ý của tôi, cộng với việc kiểm tra thực tế phát hành thêm. – IamIC

Trả lời

8

Tôi nghi ngờ bạn đang sử dụng "Chuyển sang tháo gỡ" trong khi gỡ lỗi bản xây dựng bản phát hành để lấy mã lắp ráp.

Sau khi chuyển đến Công cụ -> Tùy chọn, Gỡ lỗi, Chung và tắt "Suppress JIT optimization on load module" Tôi nhận được danh sách lắp ráp x64 mà không kiểm tra lỗi.

Dường như theo mặc định ngay cả trong chế độ phát hành, mã không được tối ưu hóa nếu trình gỡ lỗi được đính kèm. Hãy ghi nhớ điều đó khi cố gắng chuẩn mực mã của bạn.

PS: Điểm chuẩn cho thấy x64 hơi nhanh hơn x86, 4,3 so với 4,8 giây cho 1 tỷ cuộc gọi hàm.

Chỉnh sửa: Điểm ngắt vẫn hoạt động đối với tôi, nếu không tôi sẽ không thể nhìn thấy việc tháo gỡ sau khi bỏ chọn.dòng ví dụ của bạn từ trên cao trông như thế này (VS 2012 RC):

crc = (crc >> 8)^crcTable[((val & 0x0000ff00) >> 8)^crc & 0xff]; 
00000030 mov   r11d,eax 
00000033 shr   r11d,8 
00000037 mov   ecx,edx 
00000039 and   ecx,0FF00h 
0000003f shr   ecx,8 
00000042 movzx  eax,al 
00000045 xor   ecx,eax 
00000047 mov   eax,ecx 
00000049 cmp   rax,r9 
0000004c jae   00000000000000A4 
0000004e mov   eax,dword ptr [r8+rax*4+10h] 
00000053 xor   r11d,eax 
+1

Có, bạn là chính xác. Vì vậy, có vẻ như trong chế độ gỡ lỗi phát hành 64 bit, kiểm tra được thêm vào, nhưng không phải ở chế độ 32 bit. Do đó bản phát hành thực tế sẽ "sạch". – IamIC

+0

Đương nhiên, với tùy chọn đó bị vô hiệu hóa, "Đi tháo gỡ" và ngắt điểm ngừng hoạt động, vì vậy tôi không thể kiểm tra. Nhưng tôi tin rằng bạn đã trả lời câu hỏi, được hỗ trợ bởi điểm chuẩn của bạn. – IamIC

+0

Tôi không có ý tưởng làm thế nào bạn đang nhận được breakpoints để làm việc và có thể nhìn thấy tháo gỡ. Bạn có đang chạy bản phát hành 64 bit không? VS nào? – IamIC

1

Nhìn vào mã này có liên quan đến kiểm tra lỗi để truy cập crcTable. Nó đang làm giới hạn của bạn trước khi nó bắt đầu đào sâu vào mảng.

Trong mã 32-bit bạn thấy điều này

0000008e mov   ecx,dword ptr ds:[03387F38h] 
.... 
0000009e xor   eax,dword ptr [ecx+edx*4+8] 

Trong trường hợp này nó tải các địa chỉ cơ sở của mảng từ 03387F38h và sau đó sử dụng số học con trỏ tiêu chuẩn để truy cập vào các mục nhập chính xác.

Trong mã 64 bit, điều này có vẻ phức tạp hơn.

000000b0 mov   rdx,124DEE68h 
000000ba mov   rdx,qword ptr [rdx] 

này tải một địa chỉ vào RDX đăng ký

000000da mov   qword ptr [rsp+40h],rdx 
... 
00000105 mov   rax,qword ptr [rsp+40h] 
0000010a mov   rcx,qword ptr [rsp+48h] 
0000010f mov   ecx,dword ptr [rax+rcx*4+10h] 

này di chuyển địa chỉ vào stack, sau đó sau này nó di chuyển nó vào thanh ghi rax và làm việc cùng một con trỏ để truy cập mảng .

Khá nhiều thứ giữa 000000da và 00000100/00000105 dường như là mã xác thực. Phần còn lại của mã ánh xạ khá tốt giữa mã 64 bit và 32 bit, với một số sử dụng đăng ký ít tích cực hơn trong mã 64 bit.

+0

Tôi đã chỉnh sửa: Tôi đã thử nghiệm chế độ phát hành trong 32 bit và đầu ra giống hệt với bản sửa lỗi 32 bit: ngắn. Điều này chắc chắn là một vấn đề 64 bit. – IamIC

+0

@IanC Ah, rất vui được biết. Tôi đã cập nhật câu trả lời để tính đến điều đó. –

+0

Điều này thực sự bất ngờ. Việc xây dựng ở chế độ 32 bit rõ ràng sẽ dẫn đến mã nhanh hơn. Bây giờ tôi tự hỏi nếu mã 64 bit là thủng với kiểm tra giới hạn mảng và mã truy cập phức tạp. – IamIC

0

exp^crc & 0xff được biên dịch như exp^(cr & 0xff):

00000082 mov   ecx,dword ptr [ebp-40h] 
00000085 mov   ebx,0FFh 
0000008a and   ecx,ebx 
0000008c xor   edx,ecx 

bạn nên viết các biểu hiện như ?

(exp^crc) & 0xff 

Phiên bản 64 bit chắc chắn ít được tối ưu hóa hơn phiên bản 32 bit. CLR có hai trình biên dịch JIT riêng biệt.

Ngoài ra, nếu perf là ​​phê bình, hãy sử dụng mã không an toàn để xóa kiểm tra giới hạn.

+0

Rõ ràng phiên bản đầy đủ trong 64 bit nhanh hơn 12% so với 32 bit. Câu trả lời là trình gỡ lỗi đính kèm ngăn chặn tối ưu hóa trong 64 bit, nhưng không phải 32. Chỉ là cách nó được thiết lập. Mã này là CRC chuẩn. – IamIC

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