Nanashi-softプログラマ専用Windows gcc SDL


◇PS3 Linux SDLでプログラミング -SPE2基でプログラムを走らせる-

○SPE2基で実行するには?

普通にプログラムを組むと、SPE1基でしかプログラムを実行する事はできません
spe_context_run関数はブロッキングするので、SPEで処理が終わるまでそこで止まってしまいます

そこで、SPE処理に入る前にフォーク(fork)するかスレッド(thread)するかして、平行動作できるようにします
スレッド方法については前に説明していますので、ここではフォークを使ってみます

○フォークの方法

フォークの説明を簡単にすると、Unixシステムではプロセスと言う単位でプログラムが実行されています
今実行しているプロセスをもう1つコピーして同じプログラムを走らせるのがフォークです

例えばプロセスID:777で処理されているプログラムがあるとします
これをフォークすると、プロセスID:778で同じプログラムが走りだします
元の777を親プロセス、新しく生成された778を子プロセスと一般的に呼びます

フォークして、子プロセスを生成する

int pid;
pid=fork();


この返り値が0だと子プロセス、そうで無ければ親プロセスです

if (pid==0){
  //子プロセスで行う処理を記述
}
else{
  //親プロセスで行う処理を記述
}

それだけです
親プロセスが子プロセス終了を待つとか、そういう事はできなかったと思います
プロセス間通信とか、パイプで何かフラグを渡すとか、子プロセスの処理終わったらシンボリックリンクを作るとか、色々とプログラム終了を伝える手段があります(どれもUnixで普通に行われている方法なので説明は割愛します)

○プログラム

前回のSPEでプログラムを走らせるで作成した SPEで文字を表示するだけのプログラムを2基で実行してみます
但し、そのままではよく分からないので、それぞれ引数を渡します

・SPEプログラム

#include "stdio.h"
int main(unsigned long long spe, unsigned long long argp, unsigned long long envp){
  int i;
  for (i=0; i < 10; i++){
    printf("SPE %d run!!(%d)\n", argp, i);
  }

  return 0;
}


PPE側では、フォークして処理を2つに分けて、両方から SPEプログラムを実行します

#include "SDL.h"
#include "libspe2.h"

int main(int args,char *argp[]){
  //フォークする
  int pid;
  if ((pid=fork()) < 0){
    printf("fork error\n");
    return -1;
  }

  int speargp; //SPEに渡す引数
  if (pid==0){
    //子プロセス
    speargp = 2;
  }
  else{
    //親プロセス
    printf("Oya ok\n");
    speargp = 1;
  }

  //SPEプログラムロード
  spe_program_handle_t *speopen=spe_image_open("./spetest");
  if (speopen == NULL){
    printf("spe_image_open error\n");
    return -1;
  }
  spe_context_ptr_t specontext=spe_context_create(0, NULL);
  if (specontext == NULL){
    printf("spe_context_create error\n");
    return -1;
  }
  if (spe_program_load(specontext, speopen) < 0){
    printf("spe_program_load error\n");
    return -1;
  }

  //SPEプログラムラン
  spe_stop_info_t speret;
  unsigned int speentry=SPE_DEFAULT_ENTRY;
  if(spe_context_run(specontext, &speentry, 0, (void*)speargp, NULL, &speret) < 0){
    printf("spe_context_run error\n");
    return -1;
  }

  //SPEプログラム破棄
  if (spe_context_destroy(specontext) < 0){
    printf("spe_context_destroy error\n");
    return -1;
  }
  if (spe_image_close(speopen) < 0){
    printf("spe_image_close error\n");
    return -1;
  }

  return 0;
}


このプログラムを実行すると、
SPE 1 run!!(0)
SPE 1 run!!(1)
SPE 1 run!!(2)
SPE 2 run!!(0)
SPE 1 run!!(3)
SPE 2 run!!(1)
SPE 1 run!!(4)
のように、2基の SPEで処理された結果が表示されます


TOPプログラマ専用PS3 Linux SDL