changeset 0:68a98d68d62a

commit
author yutaka@localhost.localdomain
date Sun, 28 Mar 2010 19:47:00 +0900
parents
children dcd83cefb980
files Makefile include/Dma.h include/MailCommand.h include/Manager.h include/Manager.h~ include/Menu.h include/Menu.h~ include/Run.h include/SIZE.h include/Spe.h include/SpeSentry.h include/Sys.h include/params.h ppe/Manager.cc ppe/Menu.cc ppe/Spe.cc ppe/Sys.cc spe/Dma.cc spe/Run.cc spe/SpeSentry.cc
diffstat 20 files changed, 663 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,30 @@
+PPETARGET = main
+SPETARGET = spe-main
+
+.SUFFIXES:.cc .o .h
+
+PPECC  = g++
+PPELIB = -lspe2
+SPECC  = spu-g++
+SPELIB =
+
+INC = -I include
+
+PPESRC = $(shell ls ppe/*.cc)
+SPESRC = $(shell ls spe/*.cc)
+
+#PPEOBJ = $(PPESRC:.cc=.o)
+#SPEOBJ = $(SPESRC:.cc=.o)
+
+all: $(PPETARGET) $(SPETARGET)
+
+$(PPETARGET): $(PPEOBJ)
+	$(PPECC) $(PPELIB) $(INC) $(PPESRC) -o $@
+
+$(SPETARGET): $(SPEOBJ)
+	$(SPECC) $(INC) $(SPESRC) -o $@
+
+clean:
+	rm -f $(PPETARGET) $(SPETARGET)
+	rm -f ppe/*.o spe/*.o
+	rm -f ppe/*~ spe/*~ ppe/*.~ spe/*.~ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Dma.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,4 @@
+void dma_get(void *buf, unsigned int addr, int size, int tag);
+void dma_put(void *buf, unsigned int addr, int size, int tag);
+int dma_wait(int tag);
+int dma_stat(int tag);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/MailCommand.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,11 @@
+
+
+enum MailCommand {
+
+  //NON_COMMAND,
+  SPE_RUN_END,
+  SPE_START,
+  SPE_READY,
+  WANT_DATA,
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Manager.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,8 @@
+//#include "params.h"
+
+//#define SIZE (24)
+
+typedef struct {
+  spe_context_ptr_t spe;
+} thread_arg_t;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Manager.h~	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,8 @@
+#include "params.h"
+
+//#define SIZE (24)
+
+typedef struct {
+  spe_context_ptr_t spe;
+} thread_arg_t;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Menu.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,3 @@
+#include "params.h"
+
+send_params_head_t* menu(int &task_num);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Menu.h~	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,3 @@
+#include "../params.h"
+
+send_params_head_t* menu(int &task_num);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Run.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,1 @@
+void run(void *in, void *out, int data_length);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SIZE.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,1 @@
+#define SIZE 1000000*4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Spe.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,3 @@
+void *run_abs_spe(void *arg);
+void spe_run_start(spe_context_ptr_t *spe, spe_program_handle_t *prog, pthread_t *thread, int spe_num);
+void spe_run_endwait(spe_context_ptr_t *spe, pthread_t *thread, int spe_num);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SpeSentry.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,3 @@
+#include "params.h"
+
+//send_params_t send_params __attribute__((aligned(16)));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Sys.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,5 @@
+#include "params.h"
+
+void* allocate(int size);
+int size_fix(int size, int fix);
+send_params_t task_allocate(int size);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/params.h	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,27 @@
+#ifndef INCLUDED_PARAMS
+#define INCLUDED_PARAMS
+
+#define SPE_NUM (6)
+#define MAX_DMA_SIZE (1024*16)
+#define ALIGN (16)
+
+typedef struct {
+
+  unsigned long long next_task;  //8
+  unsigned long long ea_out; //8
+
+  unsigned int next_task_size;   //4
+  unsigned int size_out;     //4
+  unsigned int pin_in;       //4
+  unsigned int pin_out;      //4
+
+} send_params_head_t; //32
+
+typedef struct {
+
+  send_params_head_t *head; //next data param
+  void *buff;
+
+} send_params_t;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ppe/Manager.cc	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <libspe2.h>
+#include <pthread.h>
+#include <time.h>
+#include "Manager.h"
+#include "MailCommand.h"
+#include "SIZE.h"
+#include "Sys.h"
+#include "Spe.h"
+#include "Menu.h"
+#include "params.h"
+
+void
+send_task_params(int &head_num, int &index, send_params_head_t *head,
+		 spe_context_ptr_t spe, int &flag)
+{
+
+  unsigned int data = 0;
+
+  if ( head_num ) {
+    
+    data = (unsigned int) &head[index];
+    
+    //send task param mail 
+    spe_in_mbox_write(spe,&data,1,SPE_MBOX_ALL_BLOCKING);
+    
+    head_num--;
+    index++;
+
+  } else { //task nothing, spe run end
+    data = SPE_RUN_END;
+    flag += 1;
+    //send run end mail
+    spe_in_mbox_write(spe,&data,1,SPE_MBOX_ALL_BLOCKING);  
+    //printf("send run end mail\n");
+  }
+  
+}
+
+
+int
+main(int argc, char *argv[])
+{
+
+  spe_program_handle_t *prog;
+  //スタック上にとるのはだめだめ。malloc
+  spe_context_ptr_t spe[SPE_NUM];
+  pthread_t thread[SPE_NUM];
+
+  prog = spe_image_open("spe-main");
+  //thread run. spe run.
+  spe_run_start(spe,prog,thread,SPE_NUM);
+
+  int all_spe_run_end = SPE_NUM;
+  int flag = 0;
+
+
+  clock_t start = 0,end = 0;
+  //start = clock();
+
+  int head_num = 0;
+  send_params_head_t *head = menu(head_num);
+
+  //end = clock();  
+  //printf("task create %f\n",(double)(end-start)/CLOCKS_PER_SEC);
+
+  int index = 0;
+  unsigned int data = 0;
+
+  //mail check
+  while(flag != all_spe_run_end) {
+    
+    for (int i = 0; i < SPE_NUM; i++) {
+      if (spe_out_mbox_status(spe[i])) {
+	spe_out_mbox_read(spe[i],&data,1);
+
+	//spe wait come task
+	//ppe send task or run end request mail for spe
+	if (data == WANT_DATA) {
+	  send_task_params(head_num, index, head, spe[i], flag);
+	}
+
+      }
+
+    }// end for
+
+ 
+  }//end while mail check
+
+  spe_run_endwait(spe,thread,SPE_NUM);
+  spe_image_close(prog);
+
+
+  return 0;
+
+}
+
+/*end*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ppe/Menu.cc	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "Menu.h"
+#include "Sys.h"
+#include "params.h"
+
+//headk_num と send_param_head の値を必ず返さないと、動作しない
+
+send_params_head_t*
+menu(int &head_num) {
+
+  head_num = SPE_NUM;
+  int all_task_num = SPE_NUM*1000;
+  //int all_task_num = 1;
+  //int task_size = MAX_DMA_SIZE;
+  int task_size = 16*1024;
+  int in_size  = (task_size - sizeof(send_params_head_t)) * all_task_num;
+  int out_size = (task_size - sizeof(send_params_head_t)) * all_task_num;
+
+  float *in;
+  float *out = (float*)allocate(out_size);
+
+  int partition_size = task_size - sizeof(send_params_head_t);
+  send_params_t *send_params = (send_params_t*)allocate(sizeof(send_params_t)*all_task_num);
+
+  send_params_head_t *head = (send_params_head_t*)allocate(sizeof(send_params_head_t)*head_num);
+
+  for (int i = 0; i < all_task_num; i++) {
+
+    send_params[i] = task_allocate(task_size); // header と、in サイズを確保するよ。
+    in = (float*)send_params[i].buff;
+    
+    for (int j = 0; j < partition_size / sizeof(float); j++) {
+      in[j] = j;
+      //printf("%f\n",in[j]);
+    }
+
+  }
+
+  int task_list_length = all_task_num / head_num;
+  int index = 0;
+
+  for (int i = 0; i < head_num; i++) {
+
+    head[i].next_task = (unsigned long) send_params[index].head;
+    head[i].next_task_size = task_size;
+
+    head[i].ea_out   = (unsigned long) &out[(index * partition_size) / sizeof(float)];
+    head[i].size_out = partition_size;
+
+    head[i].pin_in   = 0;
+    head[i].pin_out  = 0;
+
+
+    for (int j = 0; j < task_list_length - 1; j++) {
+
+      //Cerium を要チェック
+
+      send_params[index].head->next_task      = (unsigned long) send_params[index+1].head;
+      send_params[index].head->next_task_size = task_size;
+
+      send_params[index].head->ea_out = (unsigned long) &out[((index) * partition_size) / sizeof(float)];
+      send_params[index].head->size_out = partition_size;
+
+      send_params[index].head->pin_in = 0;
+      send_params[index].head->pin_out = 0;
+
+      index++;
+     
+
+    }
+
+    
+    send_params[index].head->next_task      = 0;
+    send_params[index].head->next_task_size = 0;
+
+    send_params[index].head->ea_out = (unsigned long) &out[(index) * partition_size / sizeof(float)];
+
+    //printf("[PPE] %p\n",(unsigned long)send_params[index].head->ea_out);
+
+    //send_params[index].head->ea_out = 0;
+    send_params[index].head->size_out = partition_size;
+    
+    send_params[index].head->pin_in = 0;
+    send_params[index].head->pin_out = 0;
+
+    //send_params[index].head = NULL;
+    
+    index++;
+
+    
+  }
+
+  printf("return run\n");
+  
+  return head;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ppe/Spe.cc	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,39 @@
+#include <libspe2.h>
+#include <pthread.h>
+
+void *run_abs_spe(void *arg)
+{
+  spe_context_ptr_t *spe = (spe_context_ptr_t*) arg;
+
+  unsigned int entry;
+  spe_stop_info_t stop_info;
+
+  entry = SPE_DEFAULT_ENTRY;
+  spe_context_run(*spe, &entry, 0, 0, NULL, &stop_info); 
+
+  return NULL;
+}
+
+
+void
+spe_run_start(spe_context_ptr_t *spe, spe_program_handle_t *prog, pthread_t *thread, int spe_num)
+{
+
+  for (int i = 0; i < spe_num; i++) {
+    spe[i] = spe_context_create(0, NULL);
+    spe_program_load(spe[i], prog);
+    pthread_create(&thread[i], NULL, run_abs_spe, &spe[i]);
+  }
+
+}
+
+void
+spe_run_endwait(spe_context_ptr_t *spe, pthread_t *thread, int spe_num)
+{
+
+  for (int i = 0; i < spe_num; i++) {
+    pthread_join(thread[i], NULL);
+    spe_context_destroy(spe[i]);
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ppe/Sys.cc	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "Sys.h"
+
+int
+size_fix(int size, int fix)
+{
+
+  //16の倍数にする
+  size = ((size + fix -1) / fix)*fix;
+  
+  return size;
+
+}
+
+void*
+allocate(int size)
+{
+
+  int alignment = 16;
+  size = size_fix(size, alignment);
+
+  void *buff;
+  posix_memalign(&buff, alignment, size);
+  return buff;
+
+}
+
+send_params_t
+task_allocate(int size)
+{
+
+  if (size % 16) {
+    printf("allocate size is not multiple of 16\n");
+  }
+
+  char *buff;
+  int alignment = 16;
+  send_params_t send_params;
+
+  void *head;
+  posix_memalign(&head, alignment, size);
+
+  buff = (char*)head;
+  buff = buff + sizeof(send_params_head_t);
+
+  send_params.head = (send_params_head_t*)head;
+  send_params.buff = buff;
+
+  return send_params;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spe/Dma.cc	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <malloc.h>
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include "Dma.h"
+
+void
+dma_get(void *buf, unsigned int addr, int size, int tag)
+{
+
+  //printf("dma get sie %d\n",size);
+  mfc_get(buf, addr, size, tag, 0, 0);
+
+}
+
+void
+dma_put(void *buf, unsigned int addr, int size, int tag)
+{
+
+  mfc_put(buf, addr, size, tag, 0, 0);
+
+}
+
+int
+dma_wait(int tag)
+{
+
+  int dma_wait_time;
+
+  spu_writech(MFC_WrTagMask, 1 << tag);
+  
+  spu_write_decrementer(0xFFFFFFFF);
+  dma_wait_time = spu_read_decrementer();
+  
+  spu_mfcstat(MFC_TAG_UPDATE_ALL);
+  
+  dma_wait_time = dma_wait_time - spu_read_decrementer();
+
+  return dma_wait_time;
+
+}
+
+int
+dma_stat(int tag)
+{
+
+  spu_writech(MFC_WrTagMask, 1 << tag); 
+  return spu_mfcstat(MFC_TAG_UPDATE_IMMEDIATE);
+ 
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spe/Run.cc	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include "Run.h"
+
+void
+run(void *in, void *out, int data_length)
+{
+
+  for (int i = 0; i < data_length / sizeof(float); i++) {
+
+
+    
+    float *in_spe  = (float*)in;
+    float *out_spe = (float*)out;
+
+    //printf("%f\n",in_spe[i]);
+    
+    out_spe[i] = in_spe[i] + 1;
+
+    out_spe[i] = out_spe[i] + 1;
+    out_spe[i] = out_spe[i]*out_spe[i];
+    out_spe[i] = out_spe[i] + 1;
+    //printf("[SPE]int_spe %f\n",in_spe[i]);
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spe/SpeSentry.cc	Sun Mar 28 19:47:00 2010 +0900
@@ -0,0 +1,191 @@
+#include <stdio.h>
+#include <malloc.h>
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include "SpeSentry.h"
+#include "MailCommand.h"
+#include "Dma.h"
+#include "Run.h"
+
+void*
+fix_type(send_params_t *send_params, void* buff)
+{
+
+  char *p;
+  p = (char*)buff;
+  p = p + sizeof(send_params_head_t);
+
+  send_params->head = (send_params_head_t*)buff;
+  send_params->buff = p;
+
+}
+
+void*
+allocate(int size)
+{
+
+  int alignment = 16;
+  return memalign(alignment, size);
+
+}
+
+send_params_t
+task_allocate(int size)
+{
+
+  if (size % 16) {
+    //printf("allocate size is not multiple of 16\n");
+  }
+
+  char *buff;
+  send_params_t send_params;
+
+  void *head;
+  head = memalign(16, size);
+
+  buff = (char*)head;
+  buff = buff + sizeof(send_params_head_t);
+
+  send_params.head = (send_params_head_t*)head;
+  send_params.buff = buff;
+
+  return send_params;
+
+}
+
+int
+main(unsigned long long spe, unsigned long long argp, unsigned long long envp)
+{
+
+  uint32_t data;
+  int buff_num = 2;
+  int dma_wait_time = 0;
+
+  int in_tag[buff_num];
+  int out_tag[buff_num];
+
+  in_tag[0] = 0;
+  in_tag[1] = 1;
+
+  out_tag[0] = 2;
+  out_tag[1] = 3;
+
+  int head_tag = 4;
+
+  send_params_head_t *head   = (send_params_head_t*)allocate(sizeof(send_params_head_t));
+  send_params_t *send_params = (send_params_t*)allocate(sizeof(send_params_t));
+  void *input_buff[buff_num];
+  void *output_buff[buff_num];
+
+  int cur;
+
+  spu_write_out_mbox(WANT_DATA);
+
+  while(1) {
+
+    //mail check start
+    if(spu_stat_in_mbox()) {
+
+      data = spu_read_in_mbox();
+      
+      if (data == SPE_RUN_END) {
+
+	break;
+
+      } else {
+
+	//printf("[SPE] data %p\n",data);
+
+	dma_get(head, data, sizeof(send_params_head_t), head_tag);
+	dma_wait(head_tag);
+
+	input_buff[0] = allocate(head->next_task_size);
+
+	dma_get(input_buff[0], head->next_task, head->next_task_size, in_tag[0]);
+	dma_wait(in_tag[0]);
+
+	fix_type(send_params,input_buff[0]);
+
+	cur = 0;
+
+	while(1) {
+
+	  input_buff[cur^1] = allocate(send_params->head->next_task_size);	      
+	  dma_get(input_buff[cur^1], send_params->head->next_task, send_params->head->next_task_size, in_tag[cur^1]);
+	  
+	  void *in  = send_params->buff;
+
+	  //printf("hoge");
+	  output_buff[cur] = allocate(send_params->head->size_out);
+	  int data_length = send_params->head->size_out;
+
+	  
+	  //task********************************************
+	  
+	  run(in,output_buff[cur],data_length);
+	  
+	  //end*********************************************
+	  
+	  dma_put(output_buff[cur], send_params->head->ea_out, send_params->head->size_out, out_tag[cur]);
+
+	  free(input_buff[cur]);
+
+	  dma_wait(in_tag[cur^1]);
+	  dma_wait(out_tag[cur^1]);
+	  //printf("hoge");
+
+	  free(output_buff[cur^1]);
+
+	  cur ^= 1;
+
+	  fix_type(send_params,input_buff[cur]);
+
+	  if ((unsigned long)send_params->head->next_task == 0) {
+	    break;
+	  }
+	
+	}//while
+ 
+
+
+
+	  void *in  = send_params->buff;
+
+	  //printf("hoge");
+	  output_buff[cur] = allocate(send_params->head->size_out);
+	  int data_length = send_params->head->size_out;
+
+	  
+	  //task********************************************
+	  
+	  run(in,output_buff[cur],data_length);
+	  
+	  //end*********************************************
+	  
+	  dma_put(output_buff[cur], send_params->head->ea_out, send_params->head->size_out, out_tag[cur]);
+
+	  free(input_buff[cur]);
+
+	  dma_wait(out_tag[cur] | out_tag[cur^1] );
+	  free(output_buff[cur]);
+	  free(output_buff[cur^1]);
+
+
+ 
+	  spu_write_out_mbox(WANT_DATA);
+	  //printf("[SPE] send mail\n");
+	  
+      }//if
+    }//if
+    //mail check end
+
+
+  }//while
+
+
+  return 0;
+
+}
+
+
+/*end*/