Lec.05 向量化计算
什么是向量化计算#
- Array Programming
- 编译器的优化
NumPy#
什么是向量化#
- 未向量化:一堆 for 循环,每次只执行一个运算
-
向量化:张量运算、向量运算表示,并行执行
-
向量化的核心思想
- 同时多个值参与运算
- 可以时逻辑上的,也可以是实际执行上的
- 思维抽象
NumPy 基础#
创建的是 ndarray
类型。不同于 python list
是树状结构,ndarray
更像是 c 中的连续内存地址,由于 CPU 可能有 precache 操作,所以访问速度更快。
Indexing#
Title
切片获得的数组是一个指向原数组的指针,操作切片数组会改变原来数组的值
Axis#
axis = 0
指的是 most significant 方向,比如说是列方向。
运算#
- 广播机制的条件
- 两个向量维度相同
- 某个维度一个向量有,一个无
- 某个维度一个向量有,一个有但为 1
向量化计算#
Q 1#
给定一个矩阵,新的矩阵是原有矩阵每个值与它右上、右下的值的和,非法地址的值为 0
手写 SIMD 向量化#
SIMD 是什么#
- Single Instruction Multiple Data,单指令多数据流
- 在 x86 架构下,SIMD 一般和 SSE 和 AVX 等指令集联系在一起
- SSE 和 AVX 指令集中提供了大量可以单指令操作多个数据单元的指令
数据个数!=加速倍数#
- SIMD 同时操作两个数据,加速比不一定是 2
- 受到内存带宽使用、解码消耗减小等因素影响
- 如果是整个程序的一部分,那就更复杂了
越长越好?#
- 可能发热降频
- 可能成本更高
- AVX 512 甚至可能不如 AVX 2
C 向量化 SIMD#
- 基本流程
- Load 到寄存器
- 进行向量化计算
- Store 回内存
手写一个循环
然后用 SIMD 手写一遍:常见问题#
- 内存对齐
- 循环边界不确定
多数时候编译器自动向量化就够了,最后再来进行手写 SIMD 优化