正在阅读:CELL Broadband Engine软件开发环境介绍CELL Broadband Engine软件开发环境介绍

2007-06-26 11:18 出处:PConline 作者:PConline服务器频道 责任编辑:gongjianhui
1CELL BE处理器介绍回顶部

  


  1. CELL BE处理器介绍

  CELL Broadband Engine (CELL BE) 处理器是由Sony, Toshiba和IBM于2001年开始共同研发的新一代处理器。它基于新的多处理器架构—Cell Broadband Engine Architecture (CBEA)。Sony将于2006年下半年发布的新一代游戏主机—PlayStaion®3中就采用了CELL BE处理器。虽然CELL BE一开始是为多媒体应用(如游戏机和高清电视)所设计。但是,CELL BE并非仅仅是一个专用的处理器,它先进的架构使其非常适用于任何需要在极高的密度里提供海量的计算能力和数据吞吐的应用,如NGN核心设备,数字信号处理,物理模拟,生物数据分析,高性能商业和科学计算等。2005年6月,IBM和Mercury Computer Systems结成合作伙伴关系,共同研发基于CELL的嵌入式应用,以期将CELL BE应用于医疗图像,工业用途检测, 地震数据处理以及电信等领域。

  Cell BE 处理器包括一个基于PowerPC架构的控制处理单元Power Processing Element (PPE)以及8个SIMD的协处理器单元—Synergistic Processing Elements (SPE),以及用以连接PPE, 输入输出单元以及SPE的高速环形数据总线—Element Interconnect BUS (EIB)。CELL BE同时还提供了DMA指令和控制机制以用于在不同的处理单元之间提供高效的通信。PPE和SPE均为RISC结构,指令字长为32位,寻址空间为64位。SPE提供最高128位宽的SIMD的数据通路。工作在3.2GHz主频下,单个SPE对8位整型可提供51.2 Billion的峰值计算速度,对单精度浮点可提供25.6 GFlops的峰值计算速度。

  为了提高内存访问速度,CELL BE采用Rambus XDR DRAM内存,提供2个32位的数据访问通道,每个通道的访问速率为12.8GB/s。为了提高I/O访问速度,在CELL BE中采用了高速、可配置的I/O接口—7个发射通道和5个接收通道的Rambus PRAC FlexIO,FlexIO工作5GHz下时,其发送带宽和接收带宽分别为35GB/s和25GB/s。

  

 

 CELL BE 结构
 
  图 1 CELL BE 结构。

  PPE和SPE都是基于RISC架构,双发射的SIMD处理器。CELL BE中所有的处理单元,IO控制器,内存控制器都通过高速的EIB(4路128位宽的环形总线)互联。XIO接口提供与Rambus XDR内存的高速互连,FlexIO提供了高速I/O通道。PPE是一个兼容PowerPC 970架构的两路并发多线程处理器,包含一个32KB的L1 Cache(32KB的数据cache和32KB的指令cache), 256KB的L2 Cache以及一个VMX(VMX是PowerPC上的AltiVec多媒体扩展,Apple称为Velocity Engine。VMX本身就是一个向量处理单元,或者说是类似于Intel的SSE,SSE2的SIMD扩展。)单元。操作系统运行于PPE上,PPE负责对SPE进行调度,而SPE则负责主要的计算工作。SPE直接访问本地的Local Storage(LS)。它通过DMA方式访问主存,由DMA负责将指令和数据搬到LS。这种方式能够有效的减小内存读写延迟对处理器利用率的影响,因为SPE的计算和DMA传输可以并发地进行。SPE是一个高度可配置的处理单元,SPE可以被配置成不同的运行方式和存储保护(Isolation)模式。在存储保护模式下,PPU和其他SPE不能访问该SPE的LS,从而在硬件层次上提供了安全机制。这种机制在一些场合是非常有用的,如DRM。

2CELL BE 软件开发环境回顶部

  2.CELL BE 软件开发环境

  CELL BE SDK是专门为在CELL体系架构上进行软件和系统开发以及性能分析提供的一个完整的工具包。它提供了高效的开发工具和开发库,仿真环境—IBM Full-System Simulator for CELL,以及大量的技术文档。它可以在IBM Developerworks网站(http://www-128.ibm.com/developerworks/power/cell/)上免费下载得到。

  

CELL BE SDK结构.


 
  图 2 CELL BE SDK结构.

  CELL BE SDK为基于CELL架构的软件开发,提供了完整的开发环境和运行环境。


  CELL BE SDK包括以下内容:

  a.SPE Timing Tool: 用于观察和分析程序在SPE上执行时,其指令流水线的状态。
  b.IBM XL C/C++ Alpha Edition for Cell Broadband Engine (Cell BE) Processor:IBM开发的针对CELL BE处理器的C/C++编译器。
  c.Cell Broadband Engine SPE Management Library:为基于CELL BE Architecture编程模型的应用提供SPE的线程库支持。
  d.CELL BE 例程: 包含了丰富的基于CELL BE的例程以及一个详细的手把手的教程。
  e.IBM Full-System Simulator for CELL BE Processor: 提供对基于CELL BE处理器的系统级的仿真环境,包括CPU,内存以及外设的仿真。在SystemSim中,你可以运行一个完整的Linux操作系统,并且在此基础上运行和测试基于CELL BE 的应用程序。SystemSim能够对CELL BE进行功能和性能的仿真和分析,并且支持处理器层次的仿真,如中断处理,Cache, 总线等。
  f.GNU toolchain for CELL BE: SPE和PPE的交叉编译工具,这是基于GNU gcc的交叉编译器。前面提到的XL C在功能上基本兼容这个toolchain,但是不支持gcc的某些特殊的编译选项。总的来说,经XL C编译后的可执行代码的效率高于GNU toolchain for CELL BE,因为XLC是专门针对CELL BE所设计的。

  对于初次接触CELL BE编程的程序员来说,可以通过学习例程快速理解CELL BE的编程模型。同时,IBM Full-System Simulator for CELL BE提供了一个全系统的CELL BE仿真环境,开发者可以在SystemSim中运行自己开发的程序,察看结果,并且进行调试和性能分析。因此,即便没有实际的CELL BE开发板硬件,程序员也可以很容易学习和开发基于CELL BE的应用程序,并进行性能的分析和测试。

3CELL BE编程模型回顶部

  3. CELL BE编程模型

  对SPE的编程,可以采用高级语言,如C和C++。并且CELL BE的编译器及开发包已经对C/C++进行了扩展,以提供对Vector/SIMD的支持。

  实际上,对于应用程序的开发者来说,可以简单的将CELL BE看作一个9路的多处理器。由于PPE是一个双线程双发射、顺序执行的RISC处理单元,它的一个时钟周期可以处理来自两个线程的指令(即所谓硬件多线程SMT),因此加上8个SPE,同一时刻可以有10个任务在同时运行。总的来说,PPE适合作为控制和任务调度处理器,SPE则用于处理计算任务。例如,在一个IPTV机顶盒的应用中,我们可以创建多个SPE线程用于视频解码及输出。而PPU则负责创建,管理和维护这些SPE线程。PPE是一个通用的64位RISC PowerPC架构的处理器,所以对PPE的编程与普通的PowerPC的编程相同。这意味着很多针对PowerPC处理器编写的应用可以不加修改,或者很少修改之后就能移植到全新的CELL BE处理器上。

  SPE与PPE的一个关键的区别在于它们访问内存的方式。PPE通过load和store指令来直接访问主存和寄存器。而SPE通过DMA来访问主存,并且将指令和数据读取并且存入LS中,而不是直接共享主存。

  为了充分利用CELL BE的性能,需要在PPE上运行一个支持多任务的操作系统。运行在PPE上的主线程负责生成一个或多个的CELL BE任务。一个CELL BE任务有一个或者多个主线程和一些SPE线程与其关联。一个SPE线程将在一个SPE上运行,每个SPE有自己的寄存器,PC和DMA命令控制队列。主线程能够通过SPE的LS与SPE直接通信或者通过主存空间(有效地址空间)与SPE进行间接通信。

  OS根据一定的策略来调度SPE线程,它需要对系统中的CELL BE任务进行优先级划分,对SPE的执行以及主线程的调度,需要分别独立的进行。OS还负责完成SPE程序的动态加载,参数传递,对SPE事件的相应以及提供调试支持等。

  

SPE和PPE访存模式


 
  图 3 SPE和PPE访存模式。

  SPU只能从自己的LS中取指和取数,SPU应用程序使用LS地址,因此SPU的load和store指令只能访问LS。SPE的DMA控制器负责完成LS地址和系统主存之间有效地址之间的指令和数据的传送。

  CELL BE 存在多种编程模型,对于简单的SPE程序(”small” SPE program)来说,与普通的应用程序编程是类似的。我们需要将任务进行划分,针对不同的SPE编写不同的代码,每个SPE完成一个特定的任务。这种方式下,SPE不需要访问主存,只需访问LS就够了。在这种方式下,SPE的数据段、代码段的大小限制为256KB (LS的大小)。

  当数据和代码大小超过256KB时,需要使用大型SPE编程模式。在这种方式下,PPE将预留一段有效地址空间供SPE程序使用,然后将这段有效地址空间的起始地址告诉SPE,SPE则通过DMA方式访问这段内存。

  此外,在很多时候,我们需要多个SPE之间进行协同工作。因此,SPE线程之间就存在同步问题,在CELL BE中可以通过原子操作,信箱机制,SPE的信号机制,事件和中断机制,以及对共享内存的轮询方式来实现线程之间的同步。

  多个SPE线程协同工作时,有两种工作方式。一种是工作队列方式,这种方式下,一个空闲的SPE将会被分配一个任务。另外一种是流水线方式,每个SPE处理同一个任务的一部分工作,前一个SPE的输出作为后一个SPE的输入。

4Hello World!回顶部

  4. Hello World!

  在这一节,将通过一个Hello World例子来展示CELL BE编程,尤其是PPE编程和SPE编程。同时,还将介绍如何编译和生成CELL BE的可执行代码。

  在这个例子中,我们将创建8个SPE线程,每个SPE线程在屏幕上打印一句“Hello, CELL World!”的问候语。

  首先,是SPU上的执行代码,这部分很简单,与我们教科书上的Hello World类似。  

     

       /*spu.c*/
    #include <stdio.h>
    int main (unsigned long long id)
    {
        printf (“Hello, Wonderful CELL World (%llu)!\n”, id);
        return 0;
    }


  图 4 SPU上的代码,将在屏幕上打印”Hello World!”。

  PPU上的执行代码稍微复杂一些,它将负责创建8个SPE线程,并等待SPE线程的退出。如果您有Linux多线程开发的经验,将会非常容易理解以下代码,下面的代码看起来非常像Posix的线程编程。由于有SPE开发库的支持,创建和管理SPE线程,是一件轻松的事情。

  

       /* ppu.c */
    #include <stdlib.h>
    #include <stdio.h>
    #include <libspe.h>
    extern spe_program_handle_t spu;
     int main()
    {
    speid_t ids[8];
    int i;
      int st;
     for(i=0; i<8; i++){
         ids[i] = spe_create_thread(0, &spu, NULL, NULL, -1, 0);
          if (0 == ids[i]) {
            fprintf(stderr, "Failed to create spu thread\n");
            exit(-1);
         }
    }
    for (i=0; i<8; i++) {
         (void)spe_wait(ids[i], &st, 0);
   }
      return 0;
    }

  图 5 PPU上的执行代码,负责创建8个SPE线程。

  其中spe_creat_thread是SPE线程管理库中提供的函数。在这里,PPU创建了8个SPU线程,且把spu作为入口地址,然后在PPU上执行的主线程等待SPU线程结束后退出。

  编译CELL BE程序和普通的应用程序略有区别。一个SPU的binary需要转化为CESOF (Cell Embedded SPE Object Format)的方式,然后再将其与一个PPU binary链接起来。因为,一个SPU binary是不能被单独执行的(在SystemSim环境中除外)。所以,我们需要由PPU来创建一个SPU线程,然后通过这个线程在SPU上执行这段代码。而PPU binary是通过CESOF来获得SPU上这段执行代码的入口地址(有效地址)的。这部分工作通过以下两个步骤完成。首先,我们需要将SPU的源代码编译为一个可执行文件。然后通过GNU toolchain提供的ppu-embedspu工具来将其转为一个CESOF。

  在这里,我们通过GNU toolchain for CELL BE提供的交叉编译工具(spu-gcc,ppu-embedspu,ppu-ar和ppu-gcc)来编译Hello World!。

  1.首先,编译SPU上的可执行代码:
  spu-gcc -W -Wall –Wno-main -I${CELL_SDK_ROOT}/sysroot/user/spu/include -include spu_intrinsics.h -O3 -c spu.c
  spu-gcc -o spu spu.o -W1, -N ${CELL_SDK_ROOT)}/sysroot/usr/spu/lib/libc.a
  2.将SPU的对象文件转换为CESOF。ppu-embedspu有三个参数,分别为symbol name, 可执行文件名以及目标文件名。
  ppu-embedspu -m32 spu spu spu-embed.o
  ppu-ar -qcs lib_spu.a spu-embed.o
  3.编译PPU的可执行代码
ppu-gcc -W -Wall -m32 -I. -I${CELL_SDK_ROOT}/sysroot/usr/include -O3 -c ppu.c
  4.链接PPU对象和CESOF对象
ppu-gcc -o helloworld ppu.o -L${CELL_BE_ROOT}/sysroot/usr/lib -m32 -Wl,-m,elf32ppc spu/lib_spu.a –lspe

  在SystemSim环境运行helloworld,并察看运行结果。

  

在SystemSim环境中,运行Hello Wor


 
  图 6 在SystemSim环境中,运行Hello World!

  为了进一步理解CESOF对象,我们可以使用nm察看CESOF的内容。从图 7可以看到,在spu-embed.o中,有一个名为SPU的symbol,它是SPU上可执行代码的入口地址。

  

$ nm spu-embed.o
00000000 r __speelf__
00000000 d __spetoe__
00000000 D spu

  图 7 CESOF对象。其中,spu为spe_program_handle_t,即SPU线程的入口地址。

5优化应用程序回顶部

  5. 优化应用程序

  现有的PowerPC应用程序通过重新编译,基本上可以顺利的移植到CELL BE上。但是这种方式,只利用了PPU,而没有利用到SPU的计算能力。通过编译选项,CELL BE的编译器(XLC 或者 gcc)能够为应用程序进行一定程度的自动优化。不过,既然CELL BE的C/C++编译器和开发库对C和C++作了大量扩展,我们尽可以充分利用CELL BE的多处理器架构及SIMD能力,来优化应用程序。

  有了SPE开发库及扩展的intrinsics的支持,程序员可以在代码中显式的使用SIMD指令和数据结构,来指导编译器进行代码优化。SIMD优化是一个重要的工作,CELL BE的编程手册指出,原有代码经过SIMD化以后,能够大幅的提高应用程序的性能。通过对任务进行划分,将计算任务分配到多个SPU上,同样也能够有效的提高应用程序的性能。此外,通过并行编程,减少指令流水线的等待和停顿,可以提高应用程序的并行化程度。

  下面通过CELL BE编程手册中的一个例子,来展示如何通过对代码进行SIMD优化,从而提高应用程序的性能。图 8中,array_sum是一个对数组进行求和的函数。

  

      int array_sum(unsigned char nums[16])
      {
        int sum = 0;
        int i;
        for (i=0; i<16; ++i)
        {
          sum += nums[i];
        }
        return sum;
       }

  图 8 普通的求和函数,通过循环遍历数组,对数组的每个元素求和。

  下面的例子,利用CELL BE编译器对SIMD指令的支持,来消除不必要的串行循环,从而提高代码的运行效率,改进的代码如图 9。

  

   union
{
  int s[4];
  vector signed int v;
} sum;
int vectorized_sum(unsigned char nums[16])
{
    vector unsigned char v_nums;
    vector unsigned int zero = (vector unsigned int){0};
   v_nums = vec_perm(vec_ld(0, nums), vec_ld(16, nums), vec_lvsl(0, nums));
    sum.v = vec_sums((vector signed int)vec_sum4s(v_nums, zero), (vector signed int) zero);   
    return (sum.s[3]);
}

  
  图 9 利用SIMD来提高性能。

  在这个例子中,vec_perm函数从偏移地址0到16,以左对齐的方式,读入nums中的16个字节,并构成vector。vec_sums则是对两个vector求和。

  在这里,vec_sum4s将变量vnums按1/4饱和运算的方式与一个值为全0的vector进行向量求和,即相当于对nums的元素进行逐个相加。

  6.小结

  基于CBEA架构的CELL BE处理器是一个适用于高性能和多媒体计算的RISC处理器。CELL BE SDK提供了高效的软件开发库,高性能的编译器以及交叉编译的toolchain。同时,IBM Full-System Simulator提供了完整的CELL BE应用的仿真环境和性能分析工具。

  CELL BE的软件开发与普通PC的应用软件开发有所不同。CELL BE是第一个同时应用异构多核心和同时多线程SMT 技术的主流处理器, 它是一个为分布和并行处理设计的体系结构。开发者如果能够充分利用CELL BE处理器架构的优势,将能有效提高应用程序的性能。

为您推荐

加载更多
加载更多
加载更多
加载更多
加载更多
加载更多
加载更多
加载更多
加载更多

服务器论坛帖子排行

最高点击 最高回复 最新
最新资讯离线随时看 聊天吐槽赢奖品