无心人 发表于 2008-3-12 10:53:12

考虑做连续0的消除
没想好指令如何操作
最好别引入多指令

考虑移位和测试指令两种情况

无心人 发表于 2008-3-12 11:02:50

刚查了
shl能检测两个位
shl eax, 1
此时CF, OF标志组合代表了前两位的位情况
CF = 0 OF = 0表00
CF = 0 OF = 1 表01
CF= 1OF =0 表11
CF = 1 OF = 1 表10
看能利用么

无心人 发表于 2008-3-12 11:14:06

版本find_by_yaos_7

void find_by_yaos_7(DWORD a, DWORD index)
{
__asm
{
mov eax, dword ptr
mov edi, dword ptr
mov ecx, 31
loop1:
shl eax, 1
jcloop3
js loop2
// CF = 0; SF = 0; 00
shl eax, 1
sub ecx, 2
jnc loop1
jmp exit1
loop2:
//CF = 0; SF = 1; 01
sub ecx, 1
mov , ecx
add edi, 4
shl eax, 1
sub ecx, 1
jnc loop1
jmp exit1
loop3:
//CF = 1; SF = 0; 10
jsloop4
mov , ecx
add edi, 4
shl eax, 1
sub ecx, 2
jnc loop1
jmp exit1
loop4:
//CF = 1; SF = 1;11
mov , ecx
sub ecx, 1
mov , ecx
add edi, 8
shl eax, 1
sub ecx, 1
jnc loop1
jmp exit1
exit1:
mov , -1
}
}

仅在bit=1很少时弱于版本find_by_yaos_4
比其他版本均优化

无心人 发表于 2008-3-12 11:22:20

可能弄复杂了
检测SF就可以
CF:SF就是位组合的前两位

无心人 发表于 2008-3-15 20:43:04

今天想到一个更好的写法
星期一去测试
先写下来
cmovc是如果CF=1则mov

DWORD find_by_yaos_8(DWORD a, DWORD index)
{
__asm
{
mov edx, dword ptr
mov ebx, dword ptr
xor eax, eax
mov ecx, 31
loop1:
shl edx, 1
cmovc dword ptr ,ecx
adc eax, 0
sub ecx, 1
jnc loop1
mov dword ptr , -1
}
}

gxqcn 发表于 2008-3-15 21:13:51

现代编译器中的CMOV指令 http://images.5d6d.net/dz60/common/back.gif
指令在逆向常见的由编译器生成的程序时基本上见不到,这可能是因为在早期的IA-32处理器中没有CMOV指令,而最早提供CMOV指令的是 Pentium Pro处理器。因此,大多数编译器为了避免卷入向后兼容性的问题中,都不愿意使用CMOV指令。有意思的是,即使这些编译器被专门设置成是为更晚推出的处理器生成代码,编译器仍然不喜欢使用CMOV指令。实际使用CMOV指令的C/C++编译器只有两个——Intel公司的C++编译器和GCC编译器(GNU的C编译器)。当前最新版本的Microsoft C/C++ Optimizing编译器(版本为13.10.3077)即使在目标处理器已经显式定义为新一代的处理器的情况下,也不会使用CMOV指令。

关于条件传送指令(CMOVcc)CMOV,我以前也考虑过。
但查了一下指令周期表,在P4上几乎是3倍于MOV指令,所以是否划算,还得对比测试后才知道。

无心人 发表于 2008-3-15 21:46:17

关键是那几个指令几乎不相关
所以先CMOVC是否能保证在循环结束能执行完, 可以考虑
整个循环比前面算法消掉一个跳转
而且循环段指令几乎是完全不同类型的指令,并行度很高, 关联度也不高
在我改进的一系列算法里只有这个是单跳转的
其他少的2个多的7-8个
一切等测试再说 :)
希望能获得优势
===============================
这么多测试和函数不同的写法
发现了一个问题, 跳转不可怕
指令慢, 长度长, 指令阻塞才是阻碍速度根源

无心人 发表于 2008-3-15 21:53:42

http://www.intel.com/cd/ids/developer/apac/zho/dc/64bit/porting/204504.htm?page=13

《移植到 64 位平台》第 3 部分:移植您的应用
频繁的分支误预测
提高分支的可预测性能够对代码的性能产生显著的影响。分支误预测对性能的影响在基于英特尔® 64 位扩展技术的处理器上运行的 32位与 64位版应用之间变化不大。但是比较一下基于英特尔® 64 位扩展技术的处理器上运行的 32 位版应用与英特尔® 安腾® 处理器上运行的 64 位应用,就会看到两者之间存在着很大的差距(英特尔® 安腾® 架构很少放过分支误预测)。

建议:


使用英特尔® 编译器,通过 Profile Guided Basic-block Optimization 选项(/Qprof 选项)减少分支。
考虑使用英特尔编译器选项 /Qxi,以 cmov 和 fcmov 指令替换分支指令。
设计您的代码,提高分支的可预测性。
确保每一个 CALL 函数都有与之匹配的返回值。
避免数据与指令混合。
打开非常短的循环。
当分支基于随机预测的数据时,考虑对代码进行修改,使用条件 MOV 指令或者 SIMD 流指令扩展指令集(SSE)或 MMX™ 技术指令,以避免分支。例如,修改下面的代码:

无心人 发表于 2008-3-15 21:55:57

我想入手64位CPU书
好几本选择的
64位微处理器应用编程
64位微处理器及其编程
64位微处理器系统编程
都不太满意
也不知道安腾的东西到底值得学否

mathe 发表于 2008-3-16 09:29:27

使用CMOV在这里应该有明显的好处,毕竟分支预测错误的代价是很高的。3 倍MOV指令周期同分支预测失败代价相比太小了。
通过条件指令代替跳转语句这种优化技术叫If conversion,在安腾的编译器里面属于非常重要的优化技术。
如果仅仅为了学习计算机体系结构,看看安腾还是挺有用的,里面使用了很多非常创新的东西。不过这个架构
在实际应用中基本上不会被采用了,所以实际应用意义不大。
页: 1 2 3 4 5 [6] 7
查看完整版本: 一个快速得到bit位索引的算法