Cell/B.E. & SpursEngine プログラミング
Home記事一覧BBS

SpursEngineでHello World SPE!

SpursEngineでのSPE起動サンプルです。
Cell/B.E.との主な違いは、
ダウンロード:se_hellospe.tar.gz

SPE側プログラム:spe.c
#include <stdio.h>
#include <spurs/spsa/spsa.h>

int main()
{
  printf("Hello World from SPE!\n");
  return 0;
}

ホスト側プログラム:main.cpp
#include <iostream>
#include <fstream>
#include <memory>
#include <stdlib.h>
#include <spurs/spha/spha.h>
#include <spurs/common/byte_order.h>
#include <spurs/sp3/sp3_cmdif.h>

#define NUM_OF_SPE 4

using namespace std;

// SPEプログラムファイル名
const char * spe_program_name = "spe.elf";

int main(int argc, char ** argv)
{
  spha_session_t session;

  // セッションの作成
  spha_create_session(NULL, &session);

  // 通信路を確立
  spha_connect_session(session);

  // SPEプログラムファイルをオープン
  ifstream fp(spe_program_name, ios::binary);

  // ファイルサイズを調べる
  fp.seekg(0, ios::end);
  uint32_t spe_program_size = fp.tellg();
  fp.seekg(0, ios::beg);

  // バッファサイズを128の倍数に揃える
  uint32_t buffer_size = (spe_program_size + 127) & ~127;

  // SpursEngine側ローカルメモリ領域の確保
  spha_object_t buffer_obj;
  spha_create_memory(session, 0, 0, 0, buffer_size, 0, &buffer_obj);

  // メモリオブジェクトをマップ
  uint32_t buffer_ea;
  spha_map_memory(session, buffer_obj, 0, 0, 0, buffer_size, 0, &buffer_ea);

  // ホスト側バッファを確保(128バイト・アライン)
  char * buffer;
  int err = posix_memalign((void **)&buffer, 128, buffer_size);
  if (err)
  {
    abort();
  }

  // SPEプログラムファイルをロード
  fp.read(buffer, spe_program_size);

  // SpursEngine側ローカルメモリに転送
  uint32_t transfer_size = buffer_size;
  spha_data_transfer_to(session, buffer_obj, 0, buffer, &transfer_size);

  // ホスト側バッファを解放
  free(buffer);

  // SPEプログラムローダに与える引数をセット
  // エンディアン変換して渡す
  uint32_t loader_arg[4];
  loader_arg[0] = spurs_convert_ui32(buffer_ea);
  loader_arg[1] = spurs_convert_ui32(buffer_size);
  loader_arg[2] = 0;
  loader_arg[3] = 0;

  spha_thread_t spe_th[NUM_OF_SPE];
  for (int i = 0; i < NUM_OF_SPE; i++)
  {
    // SPEスレッドを作成
    spha_create_spe_thread(session, ~0, 0, SP3_SPE_LOADER_DEFAULT, loader_arg, sizeof(loader_arg), &spe_th[i]);

    // SPEスレッドを実行状態にする
    spha_resume_spe_thread(session, spe_th[i], 0, SP3_SPE_THREAD_RESUME_DEFAULT_ENTRY, NULL, 0, NULL, NULL, NULL);
  }

  for (int i = 0; i < NUM_OF_SPE; i++)
  {
    // SPEスレッドの終了を待つ
    spha_wait_spe_thread(session, spe_th[i], NULL, NULL, NULL);

    // SPEスレッドの破棄
    spha_delete_spe_thread (session, spe_th[i]);
  }

  // メモリオブジェクトをアンマップ
  spha_unmap_memory(session, buffer_ea, 0);

  // SpursEngine側ローカルメモリ領域を解放
  spha_delete_object(session, buffer_obj);

  // セッションの通信路を切断
  spha_close_session(session);

  // セッションの破棄
  spha_delete_session(session);

  return 0;
}

【コンパイル・実行】
SpursEngine Linux SDKはホームディレクトリ直下のSpursEngine_Linux_SDK_v1_5_3_2/にインストールしていることを想定しています。他の場所にインストールしている場合は、Makefileの「SPURSTOP」を修正してください。下記の関連記事でSpursEngine開発環境の構築方法を紹介しています。

tar xzf se_hellospe.tar.gz

cd se_hellospe

make

./hellospe

「Hello World from SPE!」と4回表示されたら成功です。

関連記事

PCにUbuntu 10.04 Lucid Lynxを「軽量」インストールする

PCにSpursEngine Linux SDKをインストールする