软件性能工程

2021-10-06  本文已影响0人  谭英智

矩阵相乘例子学习

pe-matrix

使用python编写:

pe-py
计算时间需要6小时

语言优化

解析

For Loop优化

原来的循环如下:

pe-for

修改顺序为:

pe-for-opt

性能表现如下:

pe-for-perf

可见for的顺序不同,性能会有非常大的差异

分析:

pe-for-an
pe-for-an-opt

从上图可见,在内存访问的连续性来说,ikj会更优

可以通过命令查看程序的缓存命中率:

valgrind --tool=cachegrind ./mm

编译优化

pe-matrix-compiler

并行优化

pe-matrix-pall

运行时间为3s

缓存使用优化

pe-matrix-multi

如果内循环计算一行C

而遗憾的是CPU L1缓存只有32k

这会导致在计算一个内循环,数据会不断的从内存读入,cache的缓存会不断的被刷走,导致运算低效

解决思路

通过减少内循环的计算量,从而减少数据被刷走的机率

pe-matrix-multi-2

如上图,如果内循环只计算C 64 * 64

可见通过减少计算C的维度,可以大大减少访存的数量

pe-matrix-multi-3
pe-matrix-s-size

递归优化

还没看懂,先贴出来

pe-matrix-split
pe-matrix-split-time

SIMD编译优化

现代CPU不仅仅提供SISD,还会提供SIMD的指令操作

通过clang和llvm的编译优化 -march=native -ffast-math可以把某些指令并行化

优化后的时间为0.7s

下面看看例子总的优化对比

pe-matrix-perf

代码简单优化技巧

数据结构

pe-link

例如通过增加链表的尾指针,来加快访问链表结尾的速度

pe-bomin

例如计算伯努利分布,可以通过先把结果在程序运行之前算出来,构造出一个数据表,那么在程序运行的时候就可以直接拿到结果了

pe-sparsit

例如一个稀疏矩阵,大部分数据都是零,而零乘以任何数都是零,是没用的计算,通过构造稀疏数据结构,既可以节省计算时间,也可以节省存储空间

例如CSR技术

pe-csr

逻辑优化

pe-exp

例如表达式a - b已经计算过一次了,那么d就可以直接取结果,来减少多一次的计算

pe-cycle

计算开根号是复杂的

那么可以两边平方来优化

pe-square pe-fast-path

例如计算x和y的距离,来加快运算的返回

pe-if

例如' '是更常见的一个符号,则可以提前判断,来减少if的运算

循环优化

pe-hoisting pe-for-unroll

减少了循环判断和++操作

pe-for-part-unroll pe-for-confus

函数优化

pe-tail-recur pe-coarsening

二进制操作优化

pe-x
pe-neg

计算机体系结构

流水线增加吞吐量

pe-pipe-line

乱序执行,解决流水线的冲突和冒险

pe-issue

分支预测

pe-predit-if

CPU遇到跳转指令的时候,由于会出现两个分支的代码,而CPU不想等待判断结果出来,为了效率,而执行下一个指令,因此,CPU会预判一条路径执行下去,如果判断对了,则提高了效率,否则,CPU会把执行的中间结果清理,并执行对的分支

并行优化

pe-quick-sort

可见如果要再优化快排的并行度,需要把partition并行化

题外话:使用堆来实现栈的功能

假设我要用堆连存储某个函数的栈的信息

归并排序优化

pe-merge-sort

问题出在merge的时间复杂度为n

通过二分并行处理merge:

pe-merge-bin
pe-merge-bin-code

可得:

串行时间:log n ^2

编译器优化

TBD

性能测量

pe-sort

这式一个排序算法的测量时间分布图

发现图像会出现非常奇怪的抖动。

他的原因是CPU随着计算的时间,会呈现出发热,此时计算机为了降温,所以把CPU的始终频率调低,导致排序出现上面的图形

问题的调整

pe-question

一般来说,要解决问题,必先发现问题

稳定的重现后,才可以比较容易的调整

最后把问题解决

测量时的问题

计算机的状态是不稳定的

测量工具

测量结果

取最小值

访存优化

pe-memory

管理

pe-single-heap
pe-multi-heap
pe-multi-heap-2
pe-heap

GC

上一篇 下一篇

猜你喜欢

热点阅读