博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
推断某个值是否在某个范围汇编优化
阅读量:6850 次
发布时间:2019-06-26

本文共 2730 字,大约阅读时间需要 9 分钟。

推断某个值是否在某个范围是否在某个区间范围的代码是经经常使用到的,处理图片是否超出某个边界范围的时候。 我像素点设置为零。 否仅仅做点别的

在这个过程中, 我们可能要进行一次饱和处理, 于是乎写以下的代码:

if (val > 0 && val < 256){     // do something}else {    // do something}

于是乎我就写了以下这样一个函数来讨论我们的问题

int32_t isRangAt1(int32_t val, int32_t min, int32_t max){    if (val > min && val < max)    {        return 1;    }    return 0;}
 这个函数非常easy, 就是推断一个value是否是在(min, max) 这个范围内,若果在返回1,否则0。 这里是用的是开区间  

当然这里我没有考虑min < max 的容错处理;

这种代码好不好呢, 我们有没有别的实现方式呢, 当然有, 至少我们能够把if语句换成条件语句。例如以下:

int32_t isRangAt2(int32_t val, int32_t min, int32_t max){    return val <= min ? 0 : val > max ?

1 : 0; }

 当然我觉得是第二个实现比叫好(从反汇编的生成的指令看)。 可是可读性可能就差一些, 我们 还有第二种实现 
int32_t isRangAt3(int32_t val, int32_t min, int32_t max){    return (val > min) ^ (val > max);}
 以上三种实现功能上都是一个样的。 可是可读性递减, 效率应该是递增,  

特别是第三种。 用了比較和异或运算实现的, 这样就消除了if语句的跳转, 从而提高效率

int32_t isRangAt4(int32_t val, int32_t min, int32_t max){    return (((uint32_t)(val - min)) >> 31) ^ (((uint32_t)(val - max)) >> 31);}

这也是汇编里面优化的一种策略, 当然这样的方法我開始我也想到能这么做。 我是通过放会变出来看出来的

这是四种方法的汇编(大家能够在ubutnu装一个交差编译工具, 这个汇编是powerpc 的)。 大家能够比較一下:

.section	".toc","aw"	.section	".text"	.align 2	.globl isRangAt1	.section	".opd","aw"	.align 2isRangAt1:	.long	.isRangAt1,.TOC.@tocbase32	.size	isRangAt1,.-isRangAt1	.previous	.type	.isRangAt1,@function	.globl	.isRangAt1.isRangAt1:.LFB11:	cmpw 7,3,4	li 9,1	li 0,0	cmpw 6,3,5	ble 7,.L4	bge 6,.L8.L5:	mr 0,9.L4:	extsw 3,0	blr.L8:	li 9,0	b .L5.LFE11:	.size	.isRangAt1,.-.isRangAt1	.globl __gxx_personality_v0	.align 2	.globl isRangAt2	.section	".opd","aw"	.align 2isRangAt2:	.long	.isRangAt2,.TOC.@tocbase32	.size	isRangAt2,.-isRangAt2	.previous	.type	.isRangAt2,@function	.globl	.isRangAt2.isRangAt2:.LFB12:	cmpw 7,3,4	li 9,1	li 0,0	cmpw 6,3,5	ble 7,.L12	ble 6,.L15.L13:	mr 0,9.L12:	extsw 3,0	blr.L15:	li 9,0	b .L13.LFE12:	.size	.isRangAt2,.-.isRangAt2	.align 2	.globl isRangAt3	.section	".opd","aw"	.align 2isRangAt3:	.long	.isRangAt3,.TOC.@tocbase32	.size	isRangAt3,.-isRangAt3	.previous	.type	.isRangAt3,@function	.globl	.isRangAt3.isRangAt3:.LFB13:	cmpw 7,3,4	li 9,1	li 0,1	cmpw 6,3,5	bgt 7,.L17	li 0,0.L17:	bgt 6,.L18	li 9,0.L18:	xor 3,0,9	extsw 3,3	blr.LFE13:	.size	.isRangAt3,.-.isRangAt3	.align 2	.globl isRangAt4	.section	".opd","aw"	.align 2isRangAt4:	.long	.isRangAt4,.TOC.@tocbase32	.size	isRangAt4,.-isRangAt4	.previous	.type	.isRangAt4,@function	.globl	.isRangAt4.isRangAt4:.LFB14:	subf 5,5,3	subf 3,4,3	xor 5,5,3	srwi 5,5,31	extsw 3,5	blr.LFE14:	.size	.isRangAt4,.-.isRangAt4	.ident	"GCC: (GNU) 4.1.1 (SDK420, $Rev: 3547 $)"

比較一下大家会发现。前面三种实现差点儿没有一样, 当然这里我想说的一下。 这个汇编是我用gcc -O3出来的结果,大家都知道跳转语句比較耗时。 所以有时候我们要提高效率, 我们能够减少代码的可读性, 消除分支跳转, 跳过效率, 非常多时候。 编译器的一些优化策略是值得我们学习的。

这些汇编指令是powerpc ppu 的, 不了解的不要紧, 看看他们的生成的指令啥的即可。 了解了解。

有错欢迎指出, 分享请标明出处。 谢谢!

感觉好的话就顶一个, 感觉不错的话就踩一个。

转载地址:http://morul.baihongyu.com/

你可能感兴趣的文章
waiting for changelog lock.
查看>>
小白学爬虫-批量部署Splash负载集群
查看>>
你离BAT之间,只差这一套Java面试题
查看>>
laravel package 推荐,数据备份
查看>>
Synchronized锁在Spring事务管理下,为啥还线程不安全?
查看>>
环境变量PATH cp命令 mv命令 文档查看cat/more/less/head/tail
查看>>
阿里云亮相2019联通合作伙伴大会,边缘计算等3款云产品助力5G时代产业数字化转型...
查看>>
dubbo源码分析-服务端发布流程-笔记
查看>>
阿里云发布Apsara SA系列混合云存储阵列
查看>>
GoJS教程:链接模版
查看>>
QListWidget方式显示缩略图
查看>>
金三银四:蚂蚁金服JAVA后端面试题及答案之二面
查看>>
Ubuntu 外网不通解决方案
查看>>
OSChina 周六乱弹 —— 历史总是惊人的相似
查看>>
MySQL 大小写
查看>>
Lync 2013部署图片赏析-证书服务安装配置
查看>>
HTML5 本地缓存 (web存储)
查看>>
tomcat redis session共享(包含redis安全设置)
查看>>
iptables中DNAT、SNAT和MASQUERADE的作用
查看>>
kvm命令学习记录
查看>>