We use cookies to improve your experience with our site.

使用MapCG进行CPU,GPU统一编程

Providing Source Code Level Portability Between CPU and GPU with MapCG

  • 摘要: 1.本文的创新点
    GPU已经发展成为一个重要的处理器,越来越多的领域开始使用GPU来加速程序。目前GPU上使用最为广泛的编程方式是CUDA。但是使用CUDA编写的程序无法运行于CPU上。这导致很多程序不得不维护两个版本:一个是CPU版本,一个是GPU版本,大大提高了软件开发和维护成本。MapCG提供了CPU,GPU统一的编程接口。程序员使用MapCG编程,只需要编写一份代码,即可让代码运行于CPU和GPU之上。同时,MapCG提供的基于MapReduce的编程接口让编程变得更加简单。
    2.实现方法
    CPU和GPU的主要区别有几方面:1)线程模型。GPU使用的编程粒度远小于CPU,同时GPU上线程之间的关系也较CPU复杂得多。2)内存模型。GPU的内存层次比CPU多,而且cache较CPU小。3)编程语言。GPU使用CUDA编程,而CPU则使用C/C++等语言。
    MapCG使用MapReduce模型进行编程,可以掩盖大部分的问题。在MapReduce程序中,程序员不需要控制线程的调度,任务分配,负载均衡等问题,因此线程模型差异所带来的困扰可以被大大减少。同时,MapReduce程序中,任务调度是由运行时系统决定的,因而运行时系统也可以较好的控制其内存访问行为。因而程序员不需要过于担心GPU上的内存层次问题。在编程语言上,CUDA与C/C++的区别在于它提供了一些专用于GPU的语言扩展。在MapCG中,程序员使用一个C/C++语言的子集编写程序,然后使用MapCG提供的简单的源代码转换工作将代码转换成CPU代码,或者GPU代码。
    MapCG的运行时系统向程序员提供了统一的接口,但是它在CPU和GPU上的实现又有较大区别。在CPU上,MapCG为每个线程使用一个哈希表。哈希表的主要作用是对中间值进行分组。在GPU上,因为线程粒度的关系,无法为每个线程提供一个独立哈希表,因此MapCG为每个GPU使用一个哈希表。为了保证同时插入的正确性,MapCG使用GPU中的原子指令实现了一个可同时插入的哈希表。
    此外,为了优化内存分配性能,MapCG还使用了一个定制的内存分配器。这个内存分配器只供MapCG存储对使用。它是一个定制的分配器,支持调速的并行malloc,但只能一次性进行free。这样的设计符合MapCG的内存使用模式,但是不适合作为通用内存分配器。
    3.结论及未来待解决的问题
    实验表明,使用MapCG,程序员可以只编写一份代码,让代码同时在CPU和GPU上运行,同时还能取得接近于手工编写的代码的性能。同时,测试还表明,MapCG的性能优于同类框架,它比Mars和Phoenix都要快。单独的实验也证明了,MapCG中使用的哈希表设计,以及定制的内存分配器对性能的提高都是很有效的。
    MapCG使用MapReduce编程模型,而MapReduce编程模型只适合某一些程序,对于有多重循环的程序,MapReduce往往比较低效,这是MapReduce固有的问题。
    目前,MapCG还不能使用GPU上的shared memory来加速程序员编写的代码,仅在内存分配器中使用了shared memory。Xiaosong Ma等人提出了使用shared memory来改进MapReduce程序在GPU上的内存访问行为,从而获取较好的性能。我们正与他们合作将这一特性加入MapCG中。
    因为CPU和GPU之间的序列化/反序列化操作,MapCG无法提供高效的CPU-GPU协同处理,我们希望在以后的工作中改进这一点。
    4.实用价值或应用前景
    MapCG为程序员提供了一个CPU/GPU统一的编程环境,这样程序员可以只编写一份代码,就能让它运行在CPU和GPU上。同时,MapCG提供的MapReduce编程模型也让编程变得更加简单。我们相信,MapCG对于降低CPU/GPU系统中的软件开发与维护成本,普及GPU使用有较大的现实意义。

     

    Abstract: Graphics processing units (GPU) have taken an important role in the general purpose computing market in recent years. At present, the common approach to programming GPU units is to write GPU specific code with low level GPU APIs such as CUDA. Although this approach can achieve good performance, it creates serious portability issues as programmers are required to write a specific version of the code for each potential target architecture. This results in high development and maintenance costs. We believe it is desirable to have a programming model which provides source code portability between CPUs and GPUs, as well as different GPUs. This would allow programmers to write one version of the code, which can be compiled and executed on either CPUs or GPUs efficiently without modification. In this paper, we propose MapCG, a MapReduce framework to provide source code level portability between CPUs and GPUs. In contrast to other approaches such as OpenCL, our framework, based on MapReduce, provides a high level programming model and makes programming much easier. We describe the design of MapCG, including the MapReduce-style high-level programming framework and the runtime system on the CPU and GPU. A prototype of the MapCG runtime, supporting multi-core CPUs and NVIDIA GPUs, was implemented. Our experimental results show that this implementation can execute the same source code efficiently on multi-core CPU platforms and GPUs, achieving an average speedup of 1.6?2.5x over previous implementations of MapReduce on eight commonly used applications.

     

/

返回文章
返回