C# 分档/换档总成差异
早上好,下午好,晚上好 在查看关闭了“抑制JIT优化(…)”选项的调试版本的汇编代码后,我注意到以下奇怪的行为(C# 分档/换档总成差异,c#,assembly,C#,Assembly,早上好,下午好,晚上好 在查看关闭了“抑制JIT优化(…)”选项的调试版本的汇编代码后,我注意到以下奇怪的行为(bitCountisulong): 相对于 int BitQuotient = (int)(bitCount >> 5); 00000110 mov eax,dword ptr [ebp+8] 00000113 mov edx,dword ptr [ebp+0Ch] 00000116 shrd e
bitCount
isulong
):
相对于
int BitQuotient = (int)(bitCount >> 5);
00000110 mov eax,dword ptr [ebp+8]
00000113 mov edx,dword ptr [ebp+0Ch]
00000116 shrd eax,edx,5
0000011a shr edx,5
0000011d mov dword ptr [ebp-44h],eax
为什么在装配上会有这样的差异?编译器不应该检测到除以32等于右移5并替换代码吗?另外,调用
指令对第一段代码做了什么?我怀疑这与运算符/
应用于非本机ulong
有关,但这也意味着编译器不内联此类运算符
编辑:查看int位余数=(int)(位计数%32)
与int位余数=(int)(位计数&31)
:
及
非常感谢。第一个代码段中的代码执行64位除法。x86抖动不会为该内联生成机器代码,会有太多的机器代码。它依赖于名为JIT_ULDiv的助手函数。这是抖动的常用策略,对于C编译器来说也是如此。您可以在SSCLI20源代码clr/src/vm/jithelpers.cpp源代码文件中看到jitter可以使用的帮助函数类型。long和ulong算法的助手函数位于文件的顶部
第二个代码段进行32位除法,只需要很少的机器代码指令即可在线生成。将除法转换为移位是一个简单的优化。比特计数的数据类型是什么?对不起。。。比特数是
ulong
;干得好,你加了那个!你是否真的分析过是否有明显的速度差异?这很可能是因为现代CPU实际上是相同的……好吧,使用秒表和32*200000000
迭代,平均差异不明显。。。但无论如何,这很奇怪。
int BitQuotient = (int)(bitCount >> 5);
00000110 mov eax,dword ptr [ebp+8]
00000113 mov edx,dword ptr [ebp+0Ch]
00000116 shrd eax,edx,5
0000011a shr edx,5
0000011d mov dword ptr [ebp-44h],eax
00000120 mov eax,dword ptr [ebp+8]
00000123 mov edx,dword ptr [ebp+0Ch]
00000126 mov ecx,20h
0000012b cmp edx,ecx
0000012d jb 00000139
0000012f mov ebx,eax
00000131 mov eax,edx
00000133 xor edx,edx
00000135 div eax,ecx
00000137 mov eax,ebx
00000139 div eax,ecx
0000013b mov eax,edx
0000013d xor edx,edx
0000013f mov dword ptr [ebp-48h],eax
00000120 mov eax,dword ptr [ebp+8]
00000123 and eax,1Fh
00000126 mov dword ptr [ebp-48h],eax