浅谈代码的执行效率(4):汇编优化

终于谈到这个话题了,首先声明我不是汇编优化的高手,甚至于我知道的所有关于汇编优化的内容,仅仅来自于学校的课程、书本及当年做过的一些简单练习。换句话说,我了解的东西只能算是一些原则,甚至也有一些“陈旧”了——不过我想既然是一些原则性的东西,还是能够用它来做一定程度的判断。至少我认为,我在博客园里看到的许多关于“汇编优化”也好,“内嵌汇编”也罢的说法,经常是有些问题的。

说到汇编优化,自然被人想到“高性能”。似乎用.NET或Java平台上的程序性能一定不佳,性能好的程序一定要用C++——不,至少一定要用C来写。为什么呢?因为一个“常识”:便是 “封装”会损失性能。性能最高的是“机器码”,因为CPU直接执行机器吗;“汇编”作为机器码的直接对应产物性能自然是一致的;C语言对于汇编/机器码几乎没有任何封装,因此性能也很好;而到了C++语言时,性能就要比C慢一些了——不过,这个看法正确吗?

其实我最近这几篇文章谈的都是与程序性能,尤其是代码执行效率有关的话题。在上一篇文章里,我们可以知道即便是在使用汇编编写代码,同样绕不开“CPU缓存”这部分与计算机体系结构相关的内容,而它对程序性能的影响甚至远远超过几句指令本身。事实上这也只是一小个方面而已,我们平时在谈性能相关问题时,总是在做很多假设,例如我们会假设不同指令的执行速度是一样的,各级别存储的读取性能也是相同的,但这都只是一个“理想环境”,和“事实”有很大差距。而进行汇编级别的优化,往往也是在利用“事实”进行细枝末节的调整。

例如,假设编译器只是对代码做“直接翻译”的话,您认为以下两种做法性能哪个比较好?

int sum = 0;
for (int i = 0; i < 100; i++)
{
   sum += array[i];
}

int sum1 = 0, sum2 = 0;
for (int i = 0; i < 100; i += 2)
{
   sum1 += array[i];
   sum2 += array[i + 1];
}

int sum = sum1 + sum2;

从算法上看,两者完全相同,但是对于CPU来说,后一种做法比前一种做法性能要高。首先,第二段代码与前者相比,一个循环内部有两个完全不相关的加法运算,这样CPU便有机会将他们并行地执行,于是性能便会更好一些。其次,第二种做法的条件跳转次数少,一般来说性能就会更好一些。因为条件跳转直到最后一刻才知道要跳向何方,因此CPU流水线就很难对代码的走向进行预测了。当然,现在CPU设计已经引入了分支预测技术,如果预测成功,效率自然较高,但如果预测失败,那么便会有比较严重的损失了。因此,有时候“我们”会尽可能想办法去减少条件跳转的次数。

例如,求一个有符号32位整数的绝对值,按照我们普通的逻辑,它应该是这样的:

if (eax < 0) eax = -eax

这显然是一个条件跳转,但是它的汇编实现也完全可以是:

cdq   // 扩展eax的符号位到edx中,如果eax是正数则edx为0否则edx为0xffffffff
xor eax, edx // 如果eax为负数,就把所有的位取反,否则不变
sub eax, edx // 如果最开始eax为负数,则把这个数字取反加一

时间: 2024-10-29 03:27:15

浅谈代码的执行效率(4):汇编优化的相关文章

浅谈代码的执行效率(3):缓存与局部性

在前两篇文章里,我们讨论了程序性能的两个方面,一是算法(广义的算法,即解决问题的方法),二是编译器.通过这两个方面,我想表达的意思是,一段程序的执行效率,是很难从表面现象得出结论的,至少从一些简单的层面,如代码的长度是几乎难以说明任何问题--因此一定要进行Profiling才能做到有效的优化.而现在,我们假设两段程序算法基本相同,编译器也只是进行简单的"翻译",那么--我们能从"表面"看出性能高下吗? 那么就从一个最简单的例子看起吧.假设DoSomethingA和D

浅谈代码的执行效率(2):编译器的威力

在上一篇文章中,我主要表达了这样一个观点:影响程序效率的关键之一是算法,而算法的选择与优化,和是否多一个赋值少一个判断的关系不大.关于算法的选择,我谈到其理论上的复杂度,并不直接反映出效率.因为在实际运用时,数据的规模,特征等等都会涉及到算法的实际效果.一个时间复杂度低的算法并不代表任何情况下的效率都高.这是"实际"和"理论"的区别之一.现在我打算来谈一下另一个比较"实际"的东西:编译器对于程序效率的影响. 那么我们先来看这样一段代码,假设有一个

浅谈代码的执行效率(1):算法是关键

前一段时间在博客园里看到这样一篇文章,那位兄弟谈到程序效率的关键是"简短".他说,"程序越简短,其可执行代码就越少,就越有效率",而在编写程序的时候,"要尽量改进我们的算法,而改进算法中最重要的一条,就是减少语句".这句话从表面上似乎正确,但我认为性能这问题不能用"简短"这种方式去思考,否则会进入一些误区.我整理了一下思路,希望可以从几个方面把详细谈一下这个问题. 首先,如果说"简短的代码效率高",那么什么

浅谈如何提高编程效率?

浅谈如何提高编程效率?1.提高工作经验 经验来自实践.平时多阅读一些技能方面的书籍和来自各网站上的优秀文章.如果说,一本书就是一个台阶,那么在人的一生中将有千万道台阶等着我去跨越.每跨越一步台阶,将得到不可估量的财富,而下一步台阶,又将带我步入一个新的境界,获取新的知识. 看到学到做到.平时有时间多看看大牛写的代码,多看看开源的项目并参与一些开源项目的编码工作.2.和大牛.勤奋的人一起工作 和大牛有经验的程序猿一起工作.和勤奋的人一起共事.永远不要相信"你改变不了环境,但可以改变自已."

浅谈onTouch先执行,还是onClick执行(详解)

有一个Button 按钮,要想为该按钮设置onClick事件和OnTouch事件 mTestButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.d(TAG, "onClick execute"); } }); mTestButton.setOnTouchListener(new View.OnTouchListener() { @Ove

浅谈新网站应该如果去做SEO优化

如题"浅谈新网站应该如果去做SEO优化",其实这个话题应该属于老生常谈的话题了,但是很多人却一直提出新站到底怎么优化才能达到更好的效果.下面根据海元工作室多年的经验,为大家简单的说下几种方法,希望对大家有所帮助. (一):在新站正式上线的时候,先去各大搜索引擎那里去提交自己的网站,适当的加几个网站的目标关键词.注意:你所提交的网站不一定就能够被收录,你要耐心点,网站提交一次就OK了,没必要经常的提交.(一般来说新站的话15--30天差不多就被收录了) (二):网站上线后,首先你要清楚,

浅谈个人域博客站的SEO优化经验

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 越来越多的人开始建立自己的Blog,不管在哪里,Blog已经成为了网络上的一个热点.网络上比较主流博客程序,如PJBlog,L-Blog:Z-Blog,O-BlogZJ-Blog等 优秀的Blog程序.现在浅谈一下个人域名的博客优化. 在竞争力强的条件下应该如何优化才能获得好的排名呢? 现在对笔者一个博客站(www.xm02.com)的优化进

浅谈提升C#正则表达式效率

说到C#的Regex,谈到最多的应该就是RegexOptions.Compiled这个东西,传说中在匹配速度方面,RegexOptions.Compiled是可以提升匹配速度的,但在启动速度上,使用了RegexOptions.Compiled情况下,通常会使启动速度慢许多,据说最多是60倍. 进行一组测试,有测试数据,才有讨论依据. 第一步,帖上测试硬件信息(呵呵,硬件有点烂:() 第二步, a.测试在没有使用RegexOptions.Compiled项时候的情况,随意使用一些内容,然后循环一万

一起谈.NET技术,浅谈提升C#正则表达式效率

说到C#的Regex,谈到最多的应该就是RegexOptions.Compiled这个东西,传说中在匹配速度方面,RegexOptions.Compiled是可以提升匹配速度的,但在启动速度上,使用了RegexOptions.Compiled情况下,通常会使启动速度慢许多,据说最多是60倍. 进行一组测试,有测试数据,才有讨论依据. 第一步,帖上测试硬件信息(呵呵,硬件有点烂:() 第二步, a.测试在没有使用RegexOptions.Compiled项时候的情况,随意使用一些内容,然后循环一万