提高性能的方法

 

1. 使用更好的硬件

 

2. 选择比较好的编程语言和编译器

 

vc6 的 strcpy, vc2008 的strcpy 性能区别极大。

 

RELEASE
1亿次循环测试结果:

strcpy = 13047

strcpy = 4500

 

check: strcpy, lstrcpy 相关API实现字符串COPY, 性能之比较

 

 

 

3. 设计扩展性很强的应用程序

 

 

a. 根据硬件的特性来设计

L1 cache->L2 cache->L3 cache -> 内存 -> 硬盘及其他存储设备

L3 cache  影响相当小

 

硬件性能比对:

如果L1  数据操作之,需要1s

那么L2   需要 4->7s

内存需要 25->150s

硬盘需要 3个星期

 

 

b. 根据程序的要求,选择正确的数据结构和算法

如:结构体之变量按大小排列

 

 

4. 对代码进行调整

 

可能基本开发完成。进行适当的调整。

 

a. 尽可能不调用代价高的API,如读写文件,socket操作等。

b. 如果一个小程序被调用很多次,尽量提高其性能。

 

 

案例说明_蜗牛:

一个IOCP服务器的设计:(传统设计)

 

  线程0

接受网络请求              工作线程1 ... 工作线程32

 

每个工作线程处理:step1. 解析请求头。step2. 根据请求,逻辑计算. step3. 读写数据库。step4. 本地分发或者转发数据。

 

 

线程0

接受网络请求

工作线程1

工作线程2

工作线程3

 

 

工作线程64

解析请求头

根据请求,逻辑计算

 

读写数据库

本地分发或者转发数据

 

新的设计方案:

  线程0

接受网络请求             

工作线程1->8 解析请求头

工作线程8->16 根据请求,逻辑计算

工作线程16->24 读写数据库

工作线程24->32 本地分发或者转发数据

 

 

线程0

接受网络请求

工作线程1

 

 

工作线程8

工作线程8

 

 

工作线程16

工作线程16

 

 

工作线程24

 

 

 

 

 

每秒操作数对比:

CPU个数:    2            4          6          8

传统方案:  5000       7600     7400     6000

新方案:      9800       17400     24000     27000

 

能够使用多个CPU并充分利用CPU及其所带的Cache的强大功能。

 

原因:每一个操作所做的事情都是一样的。各个操作的数据也是相近的。

经过一两次的循环,指令与大部分的数据都从磁盘加载到了Cache中。

 

 

总结:

x. Cache使用利正确  严重影响程序整体性能和扩展性。

y. 充分利用指令的局部性与数据之局部性。

 

 

5. 对内存的合理利用与控制:

 

a. 系统基本情况

 

任何进程都需要占用资源。包括:物理内存+虚拟内存(通常为磁盘)

 

假如进程需要使用保存在磁盘中的一个虚拟内存页面,影射到内存,然后使用。

这个过程叫做:页面错误或者页失效。

 

细节:影射到内存的过程是什么?

可能的方式1. 虚拟内存页调入内存(并影射进程内存地址到操作系统内存地址),删除虚拟内存页。

可能的方式2. 把现在的物理内存页放置到磁盘上,然后虚拟内存页调入内存,删除虚拟内存页。

 

 

系统如何管理:进程所占内存 ?

最小值: min

最大传: max

当前值: cur (基本位于min->max之间,可能>max)

 

 

操作系统会管理进程内存,这是基于操作系统本身所拥用的物理内存数来的。

可能的方式2, 这种情况发生在:物理内存不够使用的情况。

当前值>max 的情况发生在:操作系统物理内存很多的情况。

 

b. 人为控制

 

b.1. 使用VirtualLock, VirtualUnLock锁定常用内存。

这样操作系统在任何情况下,都不会存入磁盘。

 

b.2. 在进程空闲时,使用SetProcessWorkingSetSize 释放掉进程相关资源。

 

b.3. 编绎时使用:link/WS:AGGRESSIVE 指定系统在任何时候都可以对进程资源进行处理。

 

 

案例说明_泰姬陵:

页访问之性能提高:

 

方式1:

DWORD dwArray[16][4096];

 

for( int i = 0; i < 4096; i ++ )

{

       for( int j = 0; j < 16; j ++ )

       {

              DWORD dwVal = dwArray[j][i];       

       }

}

 

方式2:

DWORD dwArray[16][4096];

 

for( int i = 0; i < 16; i ++ )

{

       for( int j = 0; j < 4096; j ++ )

       {

              DWORD dwVal = dwArray[i][j];       

       }

}

 

 

方式1消费10个tick count; 方式2消费0个tick count;

方式1程序是前后跳转页访问,容易产生页失效。

 

 

有关查表法的说明:

假如我们需要x 以内的数据之相乘为多大。

代码为:int v = x * y;

 

为了提高性能,我们可能改进为:查表得到。

然而如果表及大,可能产生页失效。因此可能性能更低。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值