软件性能优化方法汇编
Posted Write the code, change the wor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件性能优化方法汇编相关的知识,希望对你有一定的参考价值。
本文主要是对平时工作和Ulrich Drepper的《What Every Programmer Should Know About Memory》中软件性能优化方法的总结归纳,主要为了方便日后快速查看和检查,不涉及方法具体细节。本文涉及的软件性能优化手段包括cache、TLB、预取、多线程、总线带宽、NUMA等。日后会不定期更新。
cache优化
跳过cache
- 对于一次性的读写操作(比如网卡收发包等),因为数据不会被重复使用,所以没有必要把数据更新到cache line中,避免换出cache中有用数据。相关方法:_mm_stream_si32/_mm_stream_load_si128等。
L1D cache优化
- 改进数据局部性,如对于数组,1)把列访问改为行访问;2)把大矩阵切分成小矩阵,使数据集为一个cache line大小。
- 如果CPU支持vectorization特性,使用SIMD (Single Instruction, Multiple Data)操作,提高指令效率。相关方法:_mm_load_sd/_mm_add_pd/_mm_mul_pd等。
- 保证Critical Word First & Early Restart能最大发挥作用,最先使用的字段(Critical Word)放在数据结构的前面。
- 按数据结构字段顺序访问字段。
- 数据结构按cache line字长对齐。相关方法:__attribute((aligned(64)), posix_memalign等
- 字段保证自然对齐,不要使用pack属性。
- 大数据结构拆分成小数据结构。
- 数组(集中)结构优于链表(分散)结构。
L1I cache优化
- 使用分支预测,以便于编译器进行代码局部化优化。相关方法:__builtin_expect或-O2、-freorder-blocks编译器选项等。
- 使用小循环代码块。
- 保证代码对齐。相关方法:-falign_fuctions/-falign_jumps/-falign_loops=cache line字长等。
L2 cache优化
- 数据集保证在L2 cache大小以内,以便减少L2 cache miss。
- 对于超过L2 cache大小的大数据集,按L2 cache大小拆分成小数据集。
TLB优化
- 减少使用页面数,减少TLB miss。相关方法:减小软件目标文件大小,减少数据集大小等。
- 关闭内核 ASLR(Address Space Layout Randomization)特性,减少TLB miss。
预取优化
- CPU自带的硬件预取。一般功能简单,如不支持跨页,不支持非线性访问,2+次cache miss后才会触发等。可酌情关闭,使用软件预取。
- 软件预取。支持跨页和非线性访问。相关方法:__mm_prefetch、-fprefetch_loop_arrays等编译器选项等。
- 使能CPU OOO(out of order)特性的推测预取。不需要软件干预。
- 使用预取线程,要注意多线程同步问题。相关方法:超线程预取等。
- 使能CPU DCA(Direct Cache Access)特性。不需要软件干预。
多线程优化
并发优化
- 分离只读变量和读写变量,减少 false sharing,减少RFO(Request For Ownership)。相关方法:只读变量用const修饰等。
- 使用线程本地变量,减少RFO。相关方法:__thread等。
- 把变量分组集中,并按cache line对齐。相关方法:把只读变量、读写变量分别定义在不同的结构体中。
原子优化
- LL/SC (Load Lock/Store Conditional)。相关方法:__sync_add_and_fetch等。
- CAS (Compare-and-Swap)。相关方法:__sync_bool_compare_and_swap等。
- Transaction Menory。
内存总线带宽优化
- 设置线程亲和性(thread affinity)。保证工作在不同数据集的线程工作在不同的核上,从而保证L1 cache不共享。
NUMA优化
- 设置内存亲和性策略。相关方法:set_mempolicy等。
- 设置VMA地址空间亲和性策略。相关方法:mbind等。
- 设置线程的CPU和内存亲和性策略:相关方法:cpuset等。
其他
通过gcc自动优化分支预测。相关方法:配置-fprofile_use、-fprofile_generate编译器选项。
把共享数据转化为独享数据。相关方法:对于只读数据,通过复制;对于读写数据,通过先在各node上累加,然后把累加结果再累加得到最终结果。
用度量工具(如massif、memuage等)发现连续分配小内存块的代码流程,重构为分配连续地址的大内存块。
用度量工具(pagein, time等)统计缺页情况。针对缺页严重模块改用大页面以便减少缺页次数。相关技术:hugetlb等。
--EOF--
以上是关于软件性能优化方法汇编的主要内容,如果未能解决你的问题,请参考以下文章