仓库源文

.. Kenneth Lee 版权所有 2020

:Authors: Kenneth Lee :Version: 1.0

讨论:OpenCL2.0SVM有什么好?


我不是专职做异构计算的,只是做平台,我看很多人对NV或者OpenCL形态的SVM颇有好感, 但我想不明白,我把我的逻辑组织出来,看看别人怎么看这个问题。

OpenCL设想的异构计算模型是这样的:

    .. figure:: _static/opencl模型.jpg

就是说,我准备数据是在Host一侧的,数据也在内存中,我的数据准备好了,但要做计算 ,Host的计算子系统不合适,我改用设备计算子系统来做。一种选择是设备计算子系统直 接用主存来做,另一种选择是先拷贝到设备内存中再做。因为总线网桥(比如PCIE网络) 常常很慢,把计算过程放在主存很难接受,所以,我们需要给后者提供软件暴露。

所以早期的OpenCL等接口就直接提供了两边独立的分配和拷贝接口,数据准备还是让主CPU 管,两边的内存都可以让主CPU管理,管理好了,通知设备计算子系统直接用设备内存开始 算。这样就搞定了。

这样的缺点是两种不同的内存是两个不同的地址空间,而且从CPU的角度和从设备的角度看 物理编址,地址都不一样。这对于处理比如有链表的数据结构,就很麻烦。因为链表的地 址信息不是一开始就发进去的,而是直接放在数据结构中的,这样Host和Kernel程序无法 使用相同的地址语义来处理数据。

这样所谓SVM,Share Virtual Memory,其实本质是两边共享地址空间。你要专门分配SVM 空间,这个空间的VA在两边是一致的。OpenCL的策略大体是:Host在SVM上写入的时候写在 Host内存,Kernel投入运行的时候,我一次,或者按按需分配的方式拷贝到设备内存, Kernel运行完了,我再一次或者按更新的情况同步回来。

这是种头痛医头脚痛医脚的直接解决方案。不能说它不好,但如果我们做新方案,完全没 有必要无缘无故背上它本身的限制啊。

首先,现在不少加速器是直连系统总线的,我又不经过网桥,干嘛我要默认就认为两边的 内存访问不一致呢?而且,大部分严肃应用都是希望有多少内存用多少内存的,如果我干 脆就知道所有内存(系统内存和设备内存)的编址和行为,这些信息都给我,我自己爱怎 么管理就怎么管理不就好了,我为什么要中间有个自作多情的智能,偷偷在我做Kernel call,map,umap的时候给我做边际效应?这种优化不是更难用?

至于你说那种根据内存是否发生了更改再单独拷贝的能力,那完全可以是个单独的功能, 比如叫clCopyIfChanged(dst, src, len)就好了。

所以,我是不认为现在的OpenCL SVM有什么高明的,没有必要成为我们的设计准则的(开 发习惯和生态支持另说,那个逻辑我们独立放),还是我Miss了什么东西?