5

EDITसी # 64-बिट रिलीज कोड का डिस्प्लेप्लोर दृश्य 32-बिट डीबग कोड से 75% लंबा है?

मैंने 32 बिट में रिलीज का परीक्षण किया, और कोड कॉम्पैक्ट था। इसलिए नीचे एक 64 बिट मुद्दा है।


मैं वीएस 2012 आरसी का उपयोग कर रहा हूं। डीबग 32 बिट है, और रिलीज 64 बिट है।

  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 

64 बिट संस्करण में सभी अतिरिक्त कोड क्या कर रहा है: नीचे डिबग तो कोड की एक पंक्ति के disassembly जारी किया जाता है? यह किसके लिए परीक्षण कर रहा है? मैंने इसे बेंचमार्क नहीं किया है, लेकिन 32 बिट कोड को बहुत तेजी से निष्पादित करना चाहिए।

संपादित

पूरे समारोह:

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

यह पूरे कार्य को देखने में मदद करेगा, न केवल इसकी एक पंक्ति। –

+3

डीबग के लिए बनाया गया है और दूसरी रिलीज के लिए अंतर की तुलना करने की कोशिश कर रहा है। कम से कम एक ही प्रजाति की तुलना करें (डीबग/डीबग या रिलीज/रिलीज)। –

+0

@ केनहाइट मैं सहमत हूं। लेकिन यह तथ्य यह है कि डीबग अधिक कॉम्पैक्ट है जिसने मेरा ध्यान खींचा, साथ ही तथ्य रिलीज किए गए चेक भी। – IamIC

उत्तर

8

मुझे संदेह है कि आप असेंबली कोड प्राप्त करने के लिए रिहाई के निर्माण को डिबग करते समय "डिस्सेप्लेस पर जाएं" का उपयोग कर रहे हैं।

टूल्स -> विकल्प, डिबगिंग, सामान्य, और अक्षम करने के बाद "मॉड्यूल लोड पर जेआईटी अनुकूलन को दबाएं" अक्षम करने के बाद मुझे त्रुटि जांच के बिना x64 असेंबली सूची मिली।

यह डिफ़ॉल्ट रूप से रिलीज मोड में लगता है जैसे डीबगर संलग्न होने पर कोड अनुकूलित नहीं किया गया है। अपने कोड को बेंचमार्क करने का प्रयास करते समय इसे ध्यान में रखें।

पीएस: बेंचमार्किंग x64 की तुलना में x64 थोड़ा तेज दिखाता है, 4.3 अरब बनाम 4.8 सेकंड 1 अरब फ़ंक्शन कॉल के लिए।

संपादित करें: ब्रेक पॉइंट अभी भी मेरे लिए काम करते हैं, अन्यथा मैं अनचेकिंग के बाद डिस्सेप्लर देखने में सक्षम नहीं होता।ऊपर से आपका उदाहरण लाइन इस (वी.एस. 2012 आर सी) की तरह दिखता है:

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

हां, आप सही हैं। तो ऐसा लगता है कि 64 बिट रिलीज डीबग मोड में, चेक जोड़े गए हैं, लेकिन 32 बिट मोड में नहीं। इसलिए वास्तविक रिलीज "साफ" होगा। – IamIC

+0

स्वाभाविक रूप से, उस विकल्प के साथ अक्षम, "डिस्सेप्लिब्स पर जाएं" और ब्रेक पॉइंट काम करना बंद कर दें, इसलिए मैं जांच नहीं कर सकता। लेकिन मेरा मानना ​​है कि आपने अपने बेंचमार्क द्वारा समर्थित प्रश्न का उत्तर दिया। – IamIC

+0

मुझे नहीं पता कि आप काम करने के लिए ब्रेकपॉइंट कैसे प्राप्त कर रहे हैं और डिस्सेप्लर देख सकते हैं। क्या आप 64 बिट रिलीज चला रहे हैं? कौन सा वीएस? – IamIC

1

कोड इस त्रुटि crcTable तक पहुँचने के लिए जाँच से संबंधित है को देखते हुए। सरणी में खुदाई शुरू होने से पहले यह आपकी सीमाएं कर रहा है।

32-बिट कोड में आप इस मामले में इस

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

देखें कि यह 03387F38h से सरणी के आधार पते लोड हो रहा है और फिर सही प्रविष्टि का उपयोग करने के मानक सूचक अंकगणित का उपयोग कर।

64-बिट कोड में यह अधिक जटिल लगता है।

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

यह लोड करता रजिस्टर RDX में एक पते

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] 

यह ढेर पर पता चलता है बाद में तो, पर यह Rax रजिस्टर में यह बढ़ता रहता है और सरणी तक पहुँचने के लिए एक ही सूचक काम करता है ।

000000da और 00000100/00000105 के बीच बहुत अधिक सब कुछ सत्यापन कोड प्रतीत होता है। 64-बिट कोड में कुछ कम आक्रामक रजिस्टर उपयोग के साथ शेष कोड 64-बिट और 32-बिट कोड के बीच बहुत अच्छे हैं।

+0

मैंने एक संपादन किया: मैंने 32 बिट में रिलीज मोड का परीक्षण किया, और आउटपुट 32 बिट डीबग के समान था: छोटा। यह निश्चित रूप से एक 64 बिट मुद्दा है। – IamIC

+0

@IanC आह, जानना अच्छा है। मैंने इसे ध्यान में रखने के लिए उत्तर अपडेट किया। –

+0

यह वास्तव में अप्रत्याशित है। 32 बिट मोड में बिल्डिंग स्पष्ट रूप से तेज कोड में परिणाम देगा। अब मैं सोच रहा हूं कि 64 बिट कोड सरणी सीमाओं और जटिल पहुंच कोड के साथ riddled है। – IamIC

0

exp^सीआरसी & 0xff exp^(करोड़ & 0xff) के रूप में संकलित किया गया है:

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

आप के रूप में अभिव्यक्ति लिखना चाहिए ?

(exp^crc) & 0xff 

64-बिट संस्करण 32-बिट संस्करण से निश्चित रूप से कम अनुकूलित है। सीएलआर में दो पृथक जेआईटी कंपाइलर कार्यान्वयन है।

इसके अलावा, यदि perf आलोचनात्मक है, तो सीमा जांच को हटाने के लिए असुरक्षित कोड का उपयोग करें।

+0

स्पष्ट रूप से 64 बिट में पूर्ण रिलीज 32 बिट की तुलना में 12% तेज है। जवाब 64 बिट में संलग्न डीबगर रोकथाम अनुकूलन है, लेकिन 32 नहीं। बस जिस तरह से स्थापित किया गया है। कोड मानक सीआरसी है। – IamIC

संबंधित मुद्दे