免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: safedead
打印 上一主题 下一主题

[C] 判断4个整数符合“第一个为1,后三个为0”的方法 [复制链接]

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
11 [报告]
发表于 2013-02-17 14:08 |只看该作者
很遗憾,C语言的规则里面就是第一个条件不满足,后面的条件就不用执行了,所以就会有这么多你看似很“糟糕”的跳转指令。
如果你本身是用汇编写的,貌似这里是C版,所以我只给出C编译器的思路;如果你本身是用C写的,那就if ((rax == 1) && (rdx == 0) && (r8 == 0) && (r9 == 0))这样朴素的方法就很好了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
12 [报告]
发表于 2013-02-17 18:07 |只看该作者
[quote][size=2][color=#000]hellioncu 发表于 2013-02-17 14:08[/color] [url=forum.php?mod=redirect&goto=findpost&pid=23785540&ptid=4067684][img]static/image/common/back.gif[/img][/url][/size]
rsi = (rax ^ 0x1) | (rdx | r8 | r9)[/quote]


到底是正牌计算机学科出来的,比我这半路出家的强多了

rax ^ 0x1         如果rax == 1, 此表达式为0, 否则非0
rdx | r8 | r9      如果rdx, r8, r9全为0,此表达式为0,否则非0
两个结果同或,满足要求为0,不满足为非零

汇编之后

movq    %rax, %rsi
xorq    $1, %rsi
orq     %rdx, %rsi
orq     %r8, %rsi
orq     %r9, %rsi
test    %rsi, %rsi
jz      .L_IS_ONE

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
13 [报告]
发表于 2013-02-17 18:22 |只看该作者
回复 10# hellioncu


受你的启发,如果想判断两个大数相等,是不是可以这么做?

512位数值1存储于xmm0, xmm1, xmm2, xmm3
512位数值2存储于xmm4, xmm5, xmm6, xmm7
128位临时变量xmm8

xmm8 = (xmm0 ^ xmm4) | (xmm1 ^ xmm5) | (xmm2 ^ xmm6) | (xmm3 ^ xmm7)
如果xmm8为0,则两个512位数值相等

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
14 [报告]
发表于 2013-02-17 20:23 |只看该作者
safedead 发表于 2013-02-17 18:22
回复 10# hellioncu


512bit,64字节,不知道你什么CPU,也许有内存比较指令更合适

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
15 [报告]
发表于 2013-02-17 20:41 来自手机 |只看该作者
这个对吗?
设rdx = 1 其余都是0 同样 rsi 能得出1

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
16 [报告]
发表于 2013-02-18 09:28 |只看该作者
回复 15# zylthinking


   
rsi为0表示4个数的条件都满足
非零值就是不同时满足(rax == 1) && (rdx == 0) && (r8 == 0) && (r9 == 0)
如果rdx = 1其他是0,得出来是非0值

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
17 [报告]
发表于 2013-02-18 09:36 |只看该作者
回复 14# hellioncu


x64
我把要计算的数据都加载到XMM寄存器了
内存访问太慢了
用SSE4指令处理xmm寄存器很方便,以384位数据为例
pextrq    $0, %xmm0, %rax        #取xmm0的低64位到rax
pextrq    $1, %xmm0, %rdx        #取xmm0的高64位到rdx
pextrq    $0, %xmm1, %r8         #取xmm1的低64位到r8
pextrq    $1, %xmm1, %r9         #取xmm1的高64位到r9
pextrq    $0, %xmm2, %r10        #取xmm2的低64位到r10
pextrq    $1, %xmm2, %r11        #取xmm2的高64位到r11
计算完毕再用PINSRQ指令写回XMM寄存器,绕开频繁内存读写开销

我的破笔记本只支持到SSE4,如果是现在的主流CPU,我就可以用到AVX指令处理256位YMM寄存器了

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
18 [报告]
发表于 2013-02-18 10:56 |只看该作者
LZ不妨用实际的工作数据测试一下,这样所谓的优化,不一定会比用最朴素的代码开优化后编译出来的快多少。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
19 [报告]
发表于 2013-02-18 11:38 |只看该作者
noword2k 发表于 2013-02-18 10:56
LZ不妨用实际的工作数据测试一下,这样所谓的优化,不一定会比用最朴素的代码开优化后编译出来的快多少。


384位有限域求逆比openssl的内联汇编快半个数量级,和GMP基本持平,并且做到了可重入
难道不值得优化么
GMP运算部分代码也是全汇编实现的

C不是最佳运算语言,至少F77可以甩C99两条大街

论坛徽章:
0
20 [报告]
发表于 2013-02-18 17:37 |只看该作者
uint64_t rax;
uint64_t rdx;
uint64_t r8;
uint64_t r9;

if (!r9 & !r8 & !rdx & rax)
{
}
else
{
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP