📄 g6.htm
字号:
<html>
<head>
<title>游戏制作</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
<!--
body { font-size: 14px}
td { font-size: 14px}
a:active { text-decoration: none}
a:link { text-decoration: none}
a:visited { color: #FFFFFF; text-decoration: none}
a:hover { text-decoration: underline}
-->
</style>
</head>
<body bgcolor="#e8ffe8">
<br>
<table width="85%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>1.7 代码优化 <br>
我对代码优化的研究并不深,归根结底是因为我并不是个很聪明的程序员。我曾经见 <br>
到过一本非常好的书,名叫<图形程序开发人员指南>,英文名是Michael Abrash's <br>
Graphics Programming Black Book Special Edition。说它好有两个原因:第一,这本 <br>
书从头到尾讲得都是程序的优化;第二,我看不懂。我想对于那些高级程序员来讲,他们 <br>
可能就根本写不出有错误的代码,或者至少他们对于防止程序错误很有一套,总之,程序 <br>
的调试对他们来讲根本就不是问题,所以他们有的是时间来研究程序的优化。而我所能讲 <br>
的显然不能与他们相比,仅仅是非常初步的内容而已。 <br>
最优化的代码就是没有代码。 <br>
我忘了这是谁曾经说过的话。但是我觉得很有道理。有时侯我们把那些外国人想象得 <br>
多么了不得,其实他们大多只是把这句话应用了一下而已。想一个巧妙的办法有时要比节 <br>
约几个指令周期有效得多。但是这与我们具体所写的代码和人的经验有关,我们很难只用 <br>
几句话就把规则说清楚。要知道,游戏的速度有时比游戏的效果重要,如果你对当前我们 <br>
最需要什么样的游戏有所了解,做起决定就会容易得多。 <br>
<br>
如果我们真的需要对某些代码进行实质性的优化,那么首先我们要搞清楚哪里最浪费 <br>
时间。我们常用Profile,VTune或自制的时间计数器来测量时间。而往往最浪费时间的代 <br>
码大都很少,多是大量的循环最占用时间。 <br>
优化的级别也有区别:算法级,语言级和指令级。 <br>
体现一个程序员水平最重要的地方就是算法。一个好的算法可以使用非常少的代码就 <br>
实现原来很复杂的操作。而它也是很难做到的。尤其这些算法经常与负载的状况有关,所 <br>
以需要比较和测试才能有好的效果。 <br>
语言级优化就是我们采用较少的C语言代码来代替冗长的。比如使用临时的指针来代 <br>
替多级的成员读取。把某些赋值语句放到多重循环的外面,使用inline函数,使用指针或 <br>
引用代替结构赋值,使用指针的移动代替内存拷贝,把初始化操作放在一开始而不是循环 <br>
之中。它所遵循的原则就是“无代码”原则,减少需要执行的语句是提高速度的最直接的 <br>
做法。一般的程序员只要做到这一层就应该可以实现比较明显的优化效果了,这样的程序 <br>
比较简捷,运行效果也比较稳定。 <br>
指令级优化则要深入得多,我对这项工作也并不十分擅长。这里所要用的语言一般是 <br>
汇编语言,调试和测试也比较复杂,程序不太容易看懂,也更容易出错,有时与硬件有关 <br>
。但是它所能实现的效果可能是一般人所不能实现的。所以这种方法一般被高级程序员所 <br>
使用,所针对的代码数量应该比较少,正是刀刃上的部分。这样的优化是以指令周期做为 <br>
单位的,所以千万要注意,不要让我们费尽心机所做的优化效果,被另外一些很低效的C <br>
代码给抵销了。 <br>
优化的内容一般有: <br>
代码替换:使用周期少的指令代替周期长的指令。比如使用左移指令代替乘数是2的倍数 <br>
的乘法。使用倒数指令(如果有的话)代替除法指令。这要求我们对80x86的每一条指令都 <br>
有很熟悉了解; <br>
减少分支预测:这是pentium 以上CPU特有的功能,它会在执行该指令前预读一些指令, <br>
但是如果有分支就会造成预读的失效; <br>
并行指令:这是pentium 以上CPU特有的多流水线的优势。两条(或多条,在pentium <br>
pro以上)参数无关的指令可以被并行执行; <br>
MMX指令:在处理大量字节型数据时我们可以用到它,一次可以处理8个字节的数据; <br>
<br>
指令的预读:在读取大量数据时,如果该数据不在缓存里,将会浪费很多时间,我们需 <br>
要提前把数据放在缓存中。这个功能大概要在pentium II的下一代CPU Katmai中才会出现 <br>
; <br>
Katmai指令:想一次处理4个单精读浮点数么?那就使用Katmai CPU 中的有关指令吧 <br>
。 <br>
<br>
在优化时要注意的问题有: <br>
第一,不要本末倒置。先优化大的内容再优化小的部分。这样我们才总能找到最耗费 <br>
时间的地方而优化它; <br>
第二,要经常比较。需要对每一种可能的方法进行比较,而不能只听信书上写的。奇 <br>
迹经常出现在这里; <br>
第三,要在效率和可读性上掌握好平衡,不要光要求速度而不管结构如何,最后造成 <br>
隐藏的错误; </td>
</tr>
</table>
<p align="center"> </p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -