又求解释:

iamnobody iamnobody 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
还是做了一个strlen()函数的测试:
my::strlen() PK std::strlen();
问题1:

我用内联汇编用scas指令写的函数用时竟然稳定地保持在std::strlen()“优化”板本的三倍,他的“优化”后的核心代码是:


01181040 mov cl,byte ptr [eax]
01181042 inc eax
01181043 test cl,cl
01181045 jne main+40h (1181040h)


然后我用内联汇编写:



size_t strlen(char* pch){

char* pcrr;
_asm{
mov edi,pch
xor ecx,ecx
cld
dec ecx
xor eax,eax
repne scasb
mov pcrr,edi

}
return pcrr - pch;
}

优化后也差不多这个样。
为什么 scasb指针会这么慢,竟然比不上普通的mov 和 jne

问题2:std::strlen()的代码也有看过,在不release时比release时快,这个之前讨论过了。下面是根据类似原理写的strlen(),想不到在我的编译器上还是被优化成了这个鸟样:


size_t strlen(char* pch){

char * pcrr = pch - 1;
int x;
do{
pcrr++;
if (((int)pcrr) & 3 == 0){
do{
pcrr += 4;
x = *(int*)pcrr;
}while(!((x - 0x01010101) & ~x & 0x80808080));
pcrr -= 4;
}
}while(*pcrr != '\0');
return pcrr - pch;
}


release后:

00121057 inc esi
00121058 cmp byte ptr [esi],0
0012105B jne main+57h (121057h)


问题2:怎么控制编译器的这种低效的优化?我记得以前它还会按照我写法四个字节比较的。以前优化后是这样的:

012610D0 mov eax,dword ptr [ebx]
012610D2 lea edx,[eax-1010101h]
012610D8 not eax
012610DA and edx,eax
012610DC add ebx,4
012610DF test edx,80808080h
012610E5 je main+90h (12610D0h)



主函数代码:

const int num = 1024 * 1024 * 32;
static char arr[num];
memset(arr,'1',num);
0118100C push 2000000h
01181011 push 31h
01181013 push offset arr (1183370h)
01181018 call memset (1181BFAh)
arr[num - 1] = 0;
clock_t beg = clock();
0118101D mov ebx,dword ptr [__imp__clock (11820D4h)]
01181023 add esp,0Ch
01181026 mov byte ptr ds:[318336Fh],0
0118102D call ebx
0118102F mov dword ptr [esp+14h],eax
int len1 = strlen(arr);
01181033 mov eax,offset arr (1183370h)
01181038 lea edx,[eax+1]
0118103B jmp main+40h (1181040h)
0118103D lea ecx,[ecx]
01181040 mov cl,byte ptr [eax]
01181042 inc eax
01181043 test cl,cl
01181045 jne main+40h (1181040h)
01181047 sub eax,edx
01181049 mov dword ptr [esp+10h],eax
clock_t mid = clock();
0118104D call ebx
0118104F mov esi,eax
int len2 = my::strlen(arr);
01181051 mov edi,offset arr (1183370h)
01181056 xor ecx,ecx
01181058 cld
01181059 dec ecx
0118105A xor eax,eax
0118105C repne scas byte ptr es:[edi]
0118105E mov dword ptr [esp+0Ch],edi
clock_t end = clock();
01181062 call ebx

...全文

相关推荐

评论 8
收藏 已收藏
分享
返回顶部
iamnobody
C++ 语言 65,214 成员 250,514 内容