CUDA 有 unified memory 还需要内存优化吗?
先说结论,不管有没有 unified memory,只要有性能要求的软件,都必需自己做优化。
因为 unified memory 的主要工作,并不是去掉了 Host Memory 与 Device Memory 之间的拷贝,而是将原有的需要人工手写的这部分代码,交给了运行时,使得这些工作对程序员透明,但是 Host2Device、Device2Host 的内存拷贝所造成的 overhead 依然存在。
其次,“内存优化”其实是一个非常宽泛的话题,他通常可以指内存生命周期的自动管理(如各种解释型语言使用的垃圾回收机制);也包括减少动态内存重复申请、释放频率提高效率;还包括用更少的内存占用量完成一样的功能(当年阿波罗登月飞船上的计算机内存只有4KB)等。
以深度学习框架 OneFlow 为例,研发团队在不依赖 unified memory
的前提下,就在框架中自己实现了对开发者透明的 Host/Device 内存管理。
在 OneFlow 中,开发者只需要使用简单的表达式:user_op::HobDeviceTag() == DeviceType::kGPU
或者 user_op::HobDeviceTag() == DeviceType::kCPU
就可以告之框架相关功能是使用 GPU 内存还是 CPU 内存,编程过程中拿到的内存地址就是对应内存空间的地址。那些烦人的内存分配、设备之间的内存拷贝、动态内存的生命周期管理统统不用操心。
除了编程易用性外,怎样使用更少的内存完成更多的工作量也是内存优化重点。很多人会认为这块应该交给硬件厂商做,同时也常认为:如果硬件厂商做得足够好,就没有软件开发者什么事情了,遗憾的是,这是一个无法达到的理想境界。因为极致的内存优化与业务逻辑强相关,而硬件厂商要兼顾通用。
举个业务逻辑相关的例子,比如做深度学习框架,假设我们有 N
个参数,那么在反向过程中,需要为这 N
个参数