Windows是一个庞大的功能丰富的系统,并且为我们提供了强大的应用程序接口,使我们可以编写功能丰富的应用程序,但正因为Windows的复杂性和应用程序接口的强大,我们往往忽视了很多技术细节,使得写出来的程序效率较低,缺乏竞争力。以下是我总结的一些提高程序效率的规则,希望对提高程序质量有帮助。
减少程序在核心态和用户态之间的切换
我们知道Windows系统中的应用程序可以在两种状态下运行-用户态和核心态,但是如果进程在两种状态之间切换,则需要耗费上千个CPU周期,这对于高质量的程序来说是绝对不能容忍的。典型的例子是用户线程互斥的临界区和互斥体(Mutex),互斥体是核心态对象,应用程序使用它时会切换到核心态,而临界区则直接在用户态下工作,所以如果可能,应该用临界区取代互斥体。
使用线程代替进程以减少系统资源的开销
在Windows系统中,进程是资源非配的单位,线程是调度的单位,因为线程共享进程的地址控件,所以与创建进程相比,创建线程可以节省大量的系统资源开销。所以对于并发计算的问题,可以尽量使用线程机制来实现。
减少线程场景切换的开销
线程为应用程序提供了并发机制,使程序的多个代码段可以“同时”运行,比如使用多个线程提高费时的IO操作,但是不是线程愈多越好呢?当然不是,线程虽然使用进程地址空间,但仍有自己的运行环境(堆栈、临时令牌等),线程场景的切换是要耗费CPU资源的,同一个计算过程(不涉及IO操作),使用两个线程来完成比使用一个线程来完成所需要的时间实际是更多。
减少内存的跨边界(页)访问
在Windows系统中,内存是以页(4KB)为单位组织的,由于Windows是虚拟存储系统,内存中的页在不用时常换出到外存中,需要用到的时候再装入内存,这样可以使一个应用程序使用比实际内存大得多得地址范围。但是内存得换入换出与CPU得执行速度相比是很费时的IO操作。下面有两段几乎完全一样的程序,在VC下编译为release版本后,前一段的执行时间是后一段的200多倍
程序1:
char buf[8][4000];
char ch;
int i, j;
for(j=0; j<4000; j++)
{
for(i=0; i<8; j++)
{
ch = buf[i][j];
}
}
程序2:
char buf[8][4000];
char ch;
int i, j;
for(i=0; i<8; j++)
{
for(j=0; j<4000; j++)
{
ch = buf[i][j];
}
}