SpursEngineでHello World SPE!
SpursEngineでのSPE起動サンプルです。Cell/B.E.との主な違いは、SPEはビッグエンディアンでホストはx86の場合リトルエンディアンなのでパラメーターやデータの受け渡しの際、エンディアン変換が必要です。PCのメインメモリ、SpursEngineのローカルメモリ(128MB)、SPEのLS(1SPEあたり256KB)と3階層のメモリがあるので、まずSpursEngineのローカルメモリに領域を確保し、メインメモリからローカルメモリに転送、その後LSへの転送を行う必要があります。CESOFオブジェクトがないのでSPEプログラムはバイナリファイルとして別に出力しておき実行時に読み込むか、独自の方法でホスト側プログラムにデータとしてリンクする必要があります。ダウンロード:se_hellospe.tar.gzSPE側プログラム: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 4using 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_close_session(session); // セッションの破棄 spha_delete_session(session); return 0;}【コンパイル・実行】SpursEngine Linux SDKはホームディレクトリ以下のSpursEngine_Linux_SDK_v1_5_3_2/にインストールしていることを想定しています。下記の関連記事で開発環境の構築方法を紹介しています。他の場所にインストールしている場合は、Makefileを修正してください。tar xzf se_hellospe.tar.gzcd se_hellospemake./hellospe「Hello World from SPE!」と4回表示されたら成功です。●関連記事PCにUbuntu 10.04 Lucid Lynxを「軽量」インストールするPCにSpursEngine Linux SDKをインストールする