Nanashi-soft○プログラマ専用○Windows gcc SDL○
前回SPEから配列を2つ読むという例を記述しました
この例の場合、配列を1つずつ転送しています
これを、同時に2つの配列を転送するようにする方法があります
ギャザーと呼ばれる機能がそれです
spu_mfcdma64を使用して転送命令を出していたのは、このような機能を持っている為です
unsigned char型の2つの配列のポインタを unsigned long型の配列に入れて、引数にして渡す例です
尚、このプログラムは libspe 2.0.1用です
・PPE側の処理
SPEから配列を2つ読むと全く同じですので、そちらを見てください
『全く同じ』と言う点がポイントです
・SPE側の処理
新しく倍のサイズのdata3を宣言します
そこに1回のDMA転送で一気にデータを持って来ます
#include "stdio.h"
#include "spu_mfcio.h"
unsigned long addrlist[2] __attribute__((aligned(16)));
//unsigned char data1[64] __attribute__((aligned(16)));
//unsigned char data2[64] __attribute__((aligned(16)));
//2つの変数を消して、倍のサイズのdata3を定義する
unsigned char data3[128] __attribute__((aligned(16)));
int main(unsigned long long spe, unsigned long long argp, unsigned long long envp){
//まずは、アドレスリストを取得
mfc_list_element_t element[1];
element[0].notify = 0;
element[0].reserved = 0;
element[0].size = sizeof(addrlist);
element[0].eal = mfc_ea2h(argp);
int tag=3;
spu_mfcdma64(&addrlist,mfc_ea2l(argp),(unsigned int)(element), sizeof(element), tag,MFC_GETL_CMD);
spu_writech(MFC_WrTagMask, 1 << tag);
spu_mfcstat(MFC_TAG_UPDATE_ALL);
//データ取得 ギャザー
//新たに配列2のエレメントを定義してこちらを使う
mfc_list_element_t element2[2];
//data1変数の転送定義
element2[0].notify = 0;
element2[0].reserved = 0;
element2[0].size = sizeof(data3)/2;
element2[0].eal = mfc_ea2l(addrlist[0]);
//data2変数の転送定義
element2[1].notify = 0;
element2[1].reserved = 0;
element2[1].size = sizeof(data3)/2;
element2[1].eal = mfc_ea2l(addrlist[1]);
//data1,data2変数の両方を定義したエレメントを元に data3変数にDMA転送する
spu_mfcdma64(&data3,mfc_ea2h(addrlist[0]),(unsigned int)(element2), sizeof(element2), tag, MFC_GETL_CMD);
spu_writech(MFC_WrTagMask, 1 << tag);
spu_mfcstat(MFC_TAG_UPDATE_ALL);
printf("data3:%d %d\n", data3[0], data3[63]);
printf("data3:%d %d\n", data3[64], data3[127]);
return 0;
}
このプログラムをビルドして実行すると
data3:0 63
data3:64 127
と表示されるはずです
data1→data2の順にきちんと転送されている事がわかります
エレメント配列は3つまで定義する事ができますので、同時に3つの配列を転送できます
実際にプログラムを行うとわかりますが、転送命令にかかるコストは大きいですので、これを知っているとかなり重宝しますよ