
软件开发
木兮清扬
《大话处理器》作者
展开
-
连载:编写高效代码(1)—编写高效代码的意义
美剧《24小时》常常有这样的例子,情报部门找到一张犯罪份子的照片,然后使用人脸识别软件在数据库中进行搜索,这通常要几十分钟,在这个时间空当内,杰克·鲍尔继续跟踪另外一条线索。遇到恐怖份子袭击时,时间就是生命,如果人脸识别软件效率更高,更早搜索出结果,就能更早的防范危险,挽救生命。 服务器软件非常注重代码效率,更高效的软件,意味着更短的客户响应时间,更少的服务器成本。对于很多互联网公司,服务器原创 2011-06-15 23:02:00 · 2291 阅读 · 0 评论 -
连载:编写高效代码(13) 数据对齐访问
在32位处理器中,一个int型变量占4个byte,假设这个变量i在内存中占据2、3、4、5这4个byte的位置,如下图所示。 数据非对齐存储 内核在访问这个数据时,会先将从0开始的4个byte读入到寄存器A中,再将从4开始的4个byte读入到寄存器B中,再将有效的数据拼成一个int数据,放在寄存器C中,可见,这种访问效率是多么的低下啊,如果变量i存储在从0开始的4个byt原创 2011-12-14 22:34:48 · 4853 阅读 · 0 评论 -
连载:编写高效代码(12) 优化内存访问——别让包袱拖垮了你
从理论上看,每条运算指令的执行时间都很短,大多数指令一个Cycle就能完成,很多时候还能一个Cycle执行多条指令,可是实际上,执行指令只是处理器要做的很少一部分工作,处理器还要从存储器中取指令,从存储器中将数据导入到寄存器中,等算完后,再将结果存入到存储器中。 处理器运算的速度像兔子赛跑一样快,但是存储器的访问速度像乌龟走路一样慢,而且越是远离内核的存储器,访问速度越慢。原创 2011-12-13 21:20:19 · 4224 阅读 · 0 评论 -
连载:编写高效代码(11) 尽量减少分支
我们在介绍处理器时,已经知道了,现在的处理器都是流水线结构,if和switch等语句会带来跳转,而跳转会打乱流水线的正常执行,影响程序的执行效率。 下面这段代码,把奇数赋一个值,把偶数赋一个值,可以用这种方式实现: for(i=0; i<100; i++){ if(i%2 == 0) { a[i] = x; }原创 2011-12-09 22:39:09 · 3396 阅读 · 0 评论 -
连载:编写高效代码(10) 在精度允许的条件下,将浮点数定点化
浮点指令要比定点指令慢很多,功耗也大很多,在精度要求不那么高的情况下,就可以将浮点数定点化,用定点指令来代替浮点指令,一个典型的例子就是alpha混合。 《反恐精英》是很多人非常喜欢的游戏,在下面的游戏截图中,一个人扔了个烟雾弹,画面呈现出半透明的烟雾效果,随着时间的推移,烟雾逐渐散去,画面恢复到原来的状态。 这种效果如果让美工来实现,那会把人累死,其实这种效果原创 2011-12-08 19:58:06 · 5220 阅读 · 0 评论 -
连载:编写高效代码(9) 减少处理器不擅长的操作——不要逼我做我不喜欢的事情
尺有所短,寸有所长,每种处理器都有自己擅长与不擅长的操作。 在与处理器配套发布的指令集手册中,都会描述每个指令的执行周期,单周期指令是处理器最喜欢的,不仅执行时间短,而且利于流水线执行。加、减、逻辑运算等,常常是单周期指令,乘、除、分支指令、浮点指令、内存存取操作等,常常需要较多的时钟周期。我们在编程时,就应该少使用执行时间长的指令。 Q:这些复杂指令都有它的用原创 2011-12-07 21:54:32 · 3564 阅读 · 1 评论 -
连载:编写高效代码(8) 空间换时间——我们总是在走,却忘了停留
时间和空间的关系,是霍金这种智商的人要研究的东西,我们只需要知道,在编程时,空间是可以换时间的,时间也是可以换空间的。 李开复在他的自传《世界因你不同》中描述了他小时候在美国学校里的一个故事,老师出了道题:“谁知道1/7等于多少?”小开复马上大声回答:“0.142857”,老师和同学们都惊呼开复是个天才,其实事实情况是,开复以前在台湾时就记下了这个答案。这就是一个典型的以空间(原创 2011-12-06 19:06:48 · 4575 阅读 · 1 评论 -
连载:编写高效代码(6)——降低数据精度
我们知道,小数点后面的位数越多,数据越精确,例如,100.11就比100.1精确,而越精确的数据,所需要的bit数也越多。浮点数有单精度和双精度2种格式,单精度浮点数占32 bit,双精度浮点数占64 bit,处理双精度的浮点数自然要比单精度浮点数慢。在fabsf()是计算单精度浮点数绝对值的函数,fabsf()就比<FONT style="FONT-SIZE: 10.5pt" fac原创 2011-06-21 22:56:00 · 2334 阅读 · 0 评论 -
连载:编写高效代码(7) 减少函数调用——不要老打断我
函数是结构化程序设计的产物,它使代码更加模块化,耦合性更低,重用性更高。不过,函数调用会带来额外的开销,除了引起跳转外,还会产生额外的指令。 人都有这样的经验,做一件事情时,如果被人打断,重新再回来做这件事情,就需要一段恢复时间,如果老是被打断,那事情就没法做了。函数调用也是这样,要进行参数压栈出栈、寄存器保存、指令跳转等。多个步骤如果程序的性能要求较高,就可以将一些小的函数直接原创 2011-12-05 19:43:44 · 5410 阅读 · 1 评论 -
连载:编写高效代码(4)—算法领域的牛人们
Niklaus Wirth--Pascal语言之父,他提出了著名公式"算法+数据结构=程序"。当然,算法不仅仅可以用在程序上,硬件也一样用,处理器上也包含了不少算法,如分支预测算法、乱序调度算法等等。Niklaus Wirth James Cooley--FFT(快速傅里叶变换)的发明人,FFT是信号处理领域使用最为广泛的算法,语音处理,无线通信都原创 2011-06-21 22:45:00 · 3042 阅读 · 2 评论 -
连载:编写高效代码(5)——选用合适的指令
处理器除了一些常用的加法、移位、乘法等指令外,还有一些完成复杂功能的指令,例如:DSP中的乘累加指令、求绝对值指令,x86中的SIMD指令等等。在用高级语言编程时,编译器常常不会使用到这些指令,而是用多条简单的指令去实现它们,这时就需要程序员自己去使用它们。 使用这些复杂指令,最直接的方式当然是写汇编语言,不过汇编语言编程难度太大,还好,编译器提供了一种方便使用汇编指令的方式原创 2011-06-21 22:50:00 · 2226 阅读 · 0 评论 -
连载:编写高效代码(3)——使用更快的算法
算法,是程序设计的灵魂。 数学家高斯小学的时候就知道了用更简洁的算法来减少计算量。高斯的老师出了道数学题:1+2+3……+100=? 在别的同学还在用一个一个加法苦算的时候,高斯很快就写出了答案5050,他的方法是用(100+1)*100/2代替了99个加法。高斯的算法 算法的优化,能明显的减少程序执行所需要的指令数,也即运算量。比较有名的快速算法包括:原创 2011-06-15 23:48:00 · 2744 阅读 · 0 评论 -
连载:编写高效代码(14) 程序、数据访问符合Cache的时间、空间局部性
Cache正是利用了程序、数据访问时的时间局部性和空间局部性,为了使Cache的访问效率最高,程序和数据的组织,也应该要符合这两个特性。最典型的例子就是二维数组的访问,下面就是一个二维数组:二维数组 如果a[i][j]在Cache中,那么a[i][j+1]就很可能也在Cache中,但是a[i+1][j]则不一定。于是代码这样写就不太好: for(j=0; j原创 2011-12-15 23:11:36 · 5533 阅读 · 2 评论