最近要在MIC机群上做分布式开发,发现有两种模式可以用:
1) offload模式:该模式和GPGPU编程思想类似,把并行度高的代码转移到local的MIC处理器上执行,其它代码仍然在CPU上执行。MIC只负责本地计算,分布式通信必须在CPU上执行。
2)symmetric模式:编译出在MIC和CPU上执行的两份二进制代码。该模式逻辑上允许MIC进行分布式通信,虽然物理上消息还是从CPU走的。这种模式编程最大的难点是load balancing问题。
通过几天探索,发现了offload模式下的各种限制:
1)由于内存地址不一样,除了值类型一维数组,在offload时无法拷贝含有引用类型数据。当然,对于任何不共享内存的体系结构而言,这点并不意外。
2)无法使用复杂的数据类型,例如iostream和smart pointer。基本上还是老老实实用C写比较好。
3)无法支持virtual function,因为offload区域内无法构造virtual table。这样一来,就不要想着面向对象里的继承和多态了。
4)除非有target特殊标记,CPU代码中的全局变量也使用不了。
5)不支持MPI代码,因为offload本身只能支持本地计算,不支持分布式通信。
6)如果offload区域内会抛异常,必须在offload区域内catch解决,不能指望异常会跑到CPU代码里。
另外,如果只考虑一台机器上的两个co-processor之间的通信,即intra-node communication,也可以用一个叫SCIF的协议。用法比MPI底层,类似于socket编程。由于不适合我的使用场景,没有深入研究。
值得一提的是,不久的将来应该会出现不含CPU,纯用MIC进行分布式计算的机群。如果想进行提前开发,不考虑利用CPU资源,其实用symmetric mode是一种非常好的选择。使用symmetric模式时,惊讶的发现原来可以只执行MIC的二进制代码,而且MIC节点的rank跟CPU一样,完美支持分布式场景。这样一来,除了Intel编译器不支持一些最新的C++语法外,原来分布式的CPU代码都不用改,感觉非常棒!MIC相对于CPU,最大的优势应该就是在这里了——代码移植性比CUDA真不是好一点两点。