Python加速科学运算的一些小技巧
目录
原地操作
使用
|
|
而不是使用
|
|
好处是内存不会复制扩展,只使用a和b的内存运算
|
|
检测内存是否一致,在下面的例子中,用Python的id()函数演示了这一点, 它提供了内存中引用对象的确切地址。 运行Y = Y + X
后,会发现id(Y)指向另一个位置。 这是因为Python首先计算Y + X,为结果分配新的内存,然后使Y指向内存中的这个新位置。
|
|
幸运的是,执行原地操作非常简单。 可以使用切片表示法将操作的结果分配给先前分配的数组,例如Y[:] = <expression>
。 为了说明这一点,首先创建一个新的矩阵Z,其形状与另一个Y相同, 使用zeros_like来分配一个全的块。
|
|
如果在后续计算中没有重复使用X, 可以使用X[:] = X + Y
或X += Y
来减少操作的内存开销。
|
|
重复使用数据使其在缓存中,按序读写数据使其可预读取
矩阵按行存储比按列存储读取更快,预读取是按行读取的
CPU多核优势可用对应并行数优化速度
注意是使用物理核心数而不是逻辑核心数,这里的逻辑核心可能是物理核心的翻倍,需要仔细查看
由于Python的多线程只是在一个核心上跑,多进程才是在多核上跑,所以优化代码时最好使用多进程优化
多进程通信最好使用队列维护,可用兼容异步并行和同步逻辑,最好只使用尽量少的队列,尽量在一步逻辑内使用同队列一次,否则更新队列会很麻烦,逻辑考虑不周全可能会有漏洞(进程锁可解决,但太麻烦了,尽量多进程内的逻辑简单)
但进程逻辑也不能太简单,否则开销比多线程还要大,任务过于简单不如使用单核多线程了
GPU上少用控制语句
GPU的同步开销过大,支持很有限,GPU跑通用计算强但控制流不强
GPU上尽量保持内存本地性
GPU的三级缓存很小
GPU上尽量使用并行
使用数千个线程(类同CPU)
GPU和CPU不要频繁互传数据
带宽限制,同步开销,都不好频繁传数据