又求解释:
还是做了一个strlen()函数的测试:
my::strlen() PK std::strlen();
问题1:
我用内联汇编用scas指令写的函数用时竟然稳定地保持在std::strlen()“优化”板本的三倍,他的“优化”后的核心代码是:
然后我用内联汇编写:
优化后也差不多这个样。
为什么 scasb指针会这么慢,竟然比不上普通的mov 和 jne
问题2:std::strlen()的代码也有看过,在不release时比release时快,这个之前讨论过了。下面是根据类似原理写的strlen(),想不到在我的编译器上还是被优化成了这个鸟样:
release后:
问题2:怎么控制编译器的这种低效的优化?我记得以前它还会按照我写法四个字节比较的。以前优化后是这样的:
主函数代码:
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
...全文
相关推荐
Luogu3.0plusplus:罗谷3.0 ++解释器,求星
语言说明 罗古3.0 ++ (确定性三栈洛谷自动机,确定性三堆叠罗古自动机)是上海洛谷网络科技有限公司于2021年推出的计算机语言。 第一版发明者@ 解释器说明 使用方式:命令行格式luogu++ fileplace解释器会自动找到.lgpp源代码和.in栈初始化(可以没有),生成输出至.out .in格式: A data0 data1 ... datan C data0 data1 ... datam 其中data0〜datan按从栈底到栈顶的顺序 .out中的data0〜datan按从栈顶到栈底依次示例: D:/code/cat.in |A 3 4 5 D:/code/cat.lgpp |1 1 |TER shell>luogu++ D:/code/cat ...a few seconds later... D:/code/cat.out |A 5 4 3
C++矩阵求逆和相乘函数
用与矩阵的求逆和两个矩阵的相乘,还有矩阵的转置和正定矩阵的特殊求逆方法
Python求导数的方法
主要介绍了Python求导数的方法,涉及Python数学运算的相关技巧,需要的朋友可以参考下
关于求余数问题的一个简单方法.doc
关于求余数问题的一个简单方法
java代码-分解数求余数
java代码-分解数求余数


