Cell Simulator |
|
With PPU outputing Hello World, it is time to incorporate the SPUs into the program. (Note: if you haven't done the previous tutorial, Configuring and writing the first Cell app, you need to have it done first.) For, ease of use, in the main directory of helloworld create hello.h:(MAMBO)/Code/helloword/hello.h:
#ifndef __hello_h__
The reason for this header file will be explained later. create hello_spu.c in the (MAMBO)/Code/helloword/spu/ directory and then edit the Makefile (in that directory) to reflect changes. Makefile:
# --------------------------------------------------------------
For hello_spu.c:
#include "../hello.h"
Now, a simple 'make' in the (MAMBO)/Code/helloword/spu/ directory should yield:
$ make
Now, back into the (MAMBO)/Code/helloword/ppu/ we need to change hello.c to actually call the SPU's hello_spu program. (Note: even if you compiled the ppu right now it doesn't have the spu's program in it.) We are creating a CESOF or an executable that contains both the executable for the PPU and for the SPU. When executed the PPU sends part of the program to each SPU for execution. So, without further ado, here is the new hello.c for the PPU:
#include <stdio.h>
For those programmers use to pthreads, this code should look similiar. One important thing to remember is that this code is running on the PPU and not the SPU. Anyways, we disect the program. To start, 'extern spe_program_handle_t hello_spu; ' is used to identify what program we want to run on the SPU (notice how the make file generated hello_spu.a in (MAMBO)/Code/helloword/spu/ directory). 'spe_gid_t gid;' is used to identify what group the SPUs are in. The group, for this tutorial, is a single general group that all the SPU threads belong too. Next, 'speid_t speids[8];' are 8 data structures to hold information about each SPU thread. (Like is it running, identify where thread is which, etc...) 'int status[8];' is used to hold any return status given by a SPU after completion. With the data strutures in place, next are operations on them. The 'spe_create_group(SCHED_OTHER, 0, 1)' function creates a simple group. Then a simple check is made ot ensure that the group was created successfully. Do these checks! You are working under a simulator that isn't completely bug-free yet. If something goes wrong you will want to find it as quickly as possible. So, after the check, another check 'spe_group_max (gid)' is made to ensure that 8 SPUs are available. If I remember correctly Sony released that each processor will have 8 SPUs, but only garauntees 7 working SPUs. So this check is mainly for the simulator. In a "real" program, you may want to check to restraints. I digress. Now the program runs from 0 to 7 to create each thread with 'spe_create_thread (gid, &hello_spu, NULL, NULL, -1, 0)' The important parameters for now are the gid, and the handle 'hello_spu' which are used to iniate a thread. The other paramemters basically say that nothing is being passed to the SPU. Naturally a check to ensure the theread creation was successfule follows. With the thread running, the PPU waits for each thread to complete with the 'spe_wait(speids[i], &status[i], 0);' command. As with pthreads, the PPU "stalls" until each SPU thread completes and returns. Finally, an assembly memory sync is issued ot ensure on memory buses are flushed. (Again, to ensure all memory operations are done.) Again, we need to update the Makefile in order to compile the new ppu code:
# --------------------------------------------------------------
A simple make should yield something like:
$ make
Now, just send 'hello' to /tmp/ and run it in the simulator. Should look like:
[root@(none) ~]# callthru source /tmp/hello > hello && chmod +x hello && ./hello
For completeness the Makefile in (MAMBO)/Code/helloword/ directory:
# --------------------------------------------------------------
(You should be able to just type 'make' in (MAMBO)/Code/helloword/ directory to compile/update all executable.)
This tutorial was the first to get SPUs working. The rest of these tutorials assume that you are capable of setting up the compiling environment, compiling, moving/executing executable, and settinging up a very simple threads (as discussed in this tutorial. On a ifnal note, the directory structure of having a general .h file in a "root" directory, with directories for PPUs and SPUs is carried out throughout these tutorials & code. You can deviate and write your own all in one directory, but that can get messy. As always, here is the code: Helloworld |