※ 引述《Muscovy (三分熟的闹钟)》之铭言:
一回神竟然引发这些有趣的讨论.
来稍微介绍一下我的工作背景: 我是在上市公司做高效能运算的单位主管.
算什么无聊东西就不要问了, 不过特别强调, 不是博弈或者加密货币. :D
我的一个 block 通常会吃掉 100%~500% CPU, 生命期介于 2~48 hours.
执行阶段占用内存大概是 20GB~30GB 之间, 偶尔会用到 memory map.
再长的话不敢做, 会分段跑, 因为 windows 会当. XD
(MacOS 稳定一百倍, 但是公司不配发, 所以... )
因此, 我想我比绝大部分的人更在意“运算效能的问题”.
在我的例子里面, 每个循环执行的时间不会低于三十分钟.
所以这些 iteration 本身的 overhead 不是问题, 因为都是毫秒级.
但是如果你关心效能的话, 拆出一堆 for-loop 才是正确的写法.
因为这种写法“对于效能”最大的好处是平行化.
怎么平行化? 几个 for-loop 就拆几只程式跑啊, 简单得很.
接下来讲的就比较难一点.
加速最重要的其实是 cache utilization.
其次是 pipeline utilization.
这种 instruction level optimization, 很重要.
我给各位一个大概的概念...
cache utilization 做得最好与最差, 执行效率大约 x50~x100 倍.
pipeline utilization 的话, 几层 pipeline 就是几倍.
反观你的 CPU 辛辛苦苦买到 12 核心, 全占满大约加速 4~5 倍.
把 12 核通通算到过热它还会降频跑, 又更慢了, 你看多废.
然后 instruction level optimization 的部分.
教科书一开始就会说:
1.) data layout & access pattern 很重要.
2.) 循环里面不要放 branch.
因为 principle 1.) 顾 cache, principle 2.) 顾 pipeline.
当然 python 本身很难做到这件事.
不过你可以去找 hardware accelerated library.
最知名的就是 tensorflow + GPGPU.
tensorflow 这咚咚不只能做 AI, 它也是高效能的线代运算核心.
一样, 为了顾效能, 你也会把自己搞成这种写法. XD
: