多核编程性能优化总结

  • 调度瓶颈的一般模式:丢包、互斥、频繁切换、同步等待
  • 算法瓶颈的一般模式:流水线问题、内存访问、TBL失效、Cache失效、编译器优化、其他
  • 用OProfile跟踪系统性能
  • 用插桩工具跟踪系统异常切换

1. Cache和内存相关
基本原理:
CACHE是基于应用程序的局部性原理,位于CPU与主存间的一种高速缓存存储器,它是为平衡CPU与主存间的速度的。当CPU访问数据时,它首先CACHE从中取,如果数据不在CACHE(称为Cache Miss),它再去访问主存,然后把访问到的数据同时加载到CACHE中(称为Cache Load)。由于指令与数据的分布,存取规律不同,CACHE又分为数据CACHE(DCACHE)和指令CACHE(ICACHE)。
根据实际需要,CACHE又分为一级CACHE(L1 CACHE),二级CACHE(L2 CACHE)(甚至三级CACHE(L3 CACHE))。L1 CACHE位于CPU内,访问速度更快,容量更小;L2 CACHE位于CPU外,访问速度比L1 CACHE慢,但比内存快(暂不考虑L3 CACHE)。下表列举了原型所用ATCA R1.0环境的Cache和内存容量和速度比例:
    容量    访问速度
L1 Cache    8K    3 Clock
L2 Cache    512K    14 Clock
Memory    2G    100 Clock
CACHE管理方式分为直接映射,全相联映射和多路组相联映射三种,一般采用多路组相联映射。 
在多路组相联映射管理方式下,Cache被划分成多路(一路也称为一个Cache Page),每路又划分为多个Cache Line,而内存被分成多页,每页的大小和路的大小相同,CPU在加载Cache时每次加载一个Cache Line,但是,内存中某页的Line0只能加载到Cache中某路的Line0,内存中某页的Linen只能加载到Cache中某路的Linen。即使Linen上有空闲,Line0的加载还是要替换掉Line0,而不会去用空闲的Linen。
在对称多处理系统(SMP)中,每个核拥有独立的L1 Cache,一个CPU的多个核之间共享L2 Cache(跟CPU相关,Intel CPU共享L2 Cache),多个CPU之间是共享内存的。由于多个CPU的Cache会映射同一块内存,硬件机制会保证Cache和内存中的数据一致,会首先标记Cache中的数据失效,下次对失效的Cache访问时会重新从内存中加载。
多个核对L2 Cache以及多个CPU对内存的访问都是串行的,当一个CPU在访问总线(内存)时,其它CPU只能等待,对L2 Cache的访问也类似,这种情况称为总线冲突。解决总线冲突的最好办法是充分利用Cache,减少对内存的访问。所以在单核环境下优化CACHE访问可以提高程序性能,加快程序执行速度;在多核环境下这种优化效果会更明显,因为它还可以提高总线利用率,减少总线冲突,提高总线吞吐率。
优化基本原则是:充分利用硬件特性,优化数据结构和算法,提高指令与数据的局部性,减少Cache失效,避免伪共享造成的性能损失,提高Cache命中率,减少系统总线竞争。

根据数据访问方式,将经常需要同时访问的数据定义在一起,提高空间局部性
用多重循环遍历多维数组时,循环控制和数组定义要一致,最外层循环对应数组第一维,最内层循环对应数组最后一维,优化空间局部性
优化算法,充分利用每次导入到Cache中的数据块,减少Cache失效,如通过循环分块。
关键小函数Inline化,提高指令Cache的命中率
利用编译器的内建函数__builtin_expect,协助分支预测。对于极少进入的分支如错误处理分支使用unlikely,对于大部分情况要进入的分支用likely,参见likely和unlikely定义。
定义结构时对结构中被频繁访问到的相关字段集中靠前定义。
多个线程独立访问的数据要分布到不同的Cache Line上,避免另外一个线程修改数据时造成本线程访问的数据所在的Cache Line也失效(也称为“伪共享”)。
为减少Cache行冲突,线程的堆栈起始地址不要是Cache Page的整数倍。(主要针对SSP)
利用硬件预取能力,调整内存引用方式, Cache连续失效的长度不超过硬件预取能力长度(跟CPU相关,如512字节)。


2.  操作系统相关
减少同步阻塞操作,减少线程切换的次数,提高处理效率。
尽可能减少进入临界区的时间,以减少临界区冲突的几率,减少阻塞,提高并发/并行执行效率。
可以将过大的临界区分割成多个小临界区,提高并行度,但是要衡量多次进入临界区的开销。
使用线程池机制,避免线程频繁创建、销毁。
计算任务和I/O任务基于线程分离。
减少同步机制的封装层次。
如果临界区冲突概率较小,选择开销较小的同步手段。
在用户空间,如果对临界区的访问大量是读操作,只有少量写操作,使用读写锁代替其它同步手段。
对单个全局变量的访问的保护可以使用原子操作。
在内核态使用信号量时,如果含有大量读操作,少量写操作,使用读写信号量rwsem代替信号量semaphore 。(主要针对SSP)
在内核中使用自旋锁时,如果含有大量读操作,少量写操作,使用读写自旋锁rw_lock代替自旋锁spinlock(主要针对SSP)


3.  进程调度相关
在同一等待点上等的进程不要很多
任务比较繁重并且频繁运行的进程要指定CPU亲和力(主要针对SSP)
进程的平均工作时间要均衡
进程的优先级差不要太大
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值