Mercurial > hg > Game > Cerium
annotate TaskManager/Cell/CellTaskManagerImpl.cc @ 923:382a48afb061 draft
fix DMA/Mail wait profiler
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 30 Jul 2010 15:24:13 +0900 |
parents | 6bd218d3f643 |
children | 178fbcc81fda |
rev | line source |
---|---|
321 | 1 #define DEBUG |
2 #include "error.h" | |
57 | 3 #include <stdio.h> |
4 #include <stdlib.h> | |
5 #include <string.h> | |
6 #include "CellTaskManagerImpl.h" | |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
7 #include "HTaskInfo.h" |
621 | 8 #include "SchedTask.h" |
635
c56f6847fb87
SimpleTask worked on Mac OS X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
631
diff
changeset
|
9 #include "MainScheduler.h" |
57 | 10 #include "types.h" |
672 | 11 #include "SysFunc.h" |
12 | |
720 | 13 static void send_alloc_reply(CellTaskManagerImpl *tm, int id, SpeThreads *speThreads); |
57 | 14 |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
15 CellTaskManagerImpl::~CellTaskManagerImpl() |
67 | 16 { |
109 | 17 delete speThreads; |
18 delete [] speTaskList; | |
19 | |
20 delete ppeManager; | |
67 | 21 } |
22 | |
57 | 23 void |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
24 CellTaskManagerImpl::init() |
57 | 25 { |
637 | 26 spe_running = 0; |
476
5fc79ff9c257
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
27 |
853 | 28 // 実行可能な HTask のリスト。 FifoTaskManager と共有される |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
29 activeTaskQueue = new HTaskInfo(); |
853 | 30 // HTask の factory。 HTaskInfo ならなんでもいい。 |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
31 htaskImpl = activeTaskQueue ; // any HTaskInfo |
853 | 32 |
65 | 33 speThreads = new SpeThreads(machineNum); |
34 speThreads->init(); | |
109 | 35 |
853 | 36 // 実行される Task 用の パイプライン用のダブルバッファ |
37 speTaskList = new TaskListInfoPtr[machineNum]; // spe上の走っている Task の配列 | |
38 taskListInfo = new TaskListInfoPtr[machineNum]; // 次に走る Task の配列 | |
476
5fc79ff9c257
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
39 |
109 | 40 for (int i = 0; i < machineNum; i++) { |
812 | 41 taskListInfo[i] = new TaskListInfo(); |
808 | 42 speTaskList[i] = new TaskListInfo(); |
109 | 43 } |
44 | |
321 | 45 // PPE 側の管理をする Manager |
835 | 46 ppeManager = new FifoTaskManagerImpl(machineNum); |
479
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
476
diff
changeset
|
47 // 大半のTaskQueueInfoは、共有される |
637 | 48 MainScheduler *mscheduler = new MainScheduler; |
873
c50f39fbb6ca
fix hash problem ( unsigned int-> long overflow )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
860
diff
changeset
|
49 set_scheduler(mscheduler); |
853 | 50 ppeManager->init(mscheduler, this); // ここで HTaskInfo が共有される。 |
619 | 51 |
52 ppeManager->get_scheduler()->set_manager(this); | |
637 | 53 |
853 | 54 // Task 内からManager->task_create() とかするときに必要なTaskManager。 |
55 // 現状では ppe 側からしか動かない | |
56 // spe 側から Task create できない | |
619 | 57 schedTaskManager = new SchedTask(); |
58 schedTaskManager->init(0,0,0,ppeManager->get_scheduler()); | |
57 | 59 } |
60 | |
109 | 61 void |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
62 CellTaskManagerImpl::append_activeTask(HTaskPtr task) |
109 | 63 { |
64 if (task->cpu_type == CPU_PPE) { | |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
65 ppeManager->append_activeTask(task); |
109 | 66 } else { |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
67 activeTaskQueue->addLast(task); |
109 | 68 } |
69 } | |
70 | |
321 | 71 // SPE_ANY が指定されていた時に |
72 // これをインクリメントしつつ呼ぶことにする。 | |
73 // 乱数使ってもいいけどさ。 | |
109 | 74 int cur_anySpeid = 0; |
75 | |
76 /** | |
321 | 77 * ActiveTaskQueue から Task を |
78 * 各 SPE に渡す TaskList に入れる | |
109 | 79 * |
321 | 80 * ここの activeTaskQueue は FifoTaskManagerImpl のと意味が違い、 |
81 * spe に渡される Task だけ入っている | |
109 | 82 */ |
83 void | |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
84 CellTaskManagerImpl::set_runTaskList() |
70 | 85 { |
109 | 86 int speid; |
70 | 87 |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
88 while (HTaskPtr htask = activeTaskQueue->poll()) { |
70 | 89 |
109 | 90 if (htask->cpu_type == SPE_ANY) { |
91 speid = cur_anySpeid++; | |
92 cur_anySpeid = (cur_anySpeid < machineNum) | |
93 ? cur_anySpeid : 0; | |
70 | 94 } else { |
321 | 95 // -1 してるのは |
96 // htask->cpu_type - CPU_SPE で | |
97 // SPE0 = 1, SPE1 = 2, ... SPE5 = 6 ってなってるので | |
98 // 配列的 (SPE0 = arr[0], SPE1 = arr[1]) にするため | |
109 | 99 speid = htask->cpu_type - CPU_SPE - 1; |
100 | |
321 | 101 // SPU の数以上が指定されていれば |
102 // とりあえず MAX_USE_SPE_NUM (実際に動く SPE の最大数) で | |
103 // あまり求めてそれを使うことにする。 | |
104 // ここで判定するもんでもないか? | |
109 | 105 if (speid >= machineNum) { |
106 speid %= machineNum; | |
107 } | |
70 | 108 } |
808 | 109 set_taskList(htask, taskListInfo[speid]); |
70 | 110 } |
109 | 111 } |
112 | |
113 void | |
722 | 114 CellTaskManagerImpl::sendTaskList() |
721 | 115 { |
116 for (int i = 0; i < machineNum; i++) { | |
808 | 117 if ( taskListInfo[i]->length() > 0 ) { |
721 | 118 send_taskList(i); |
119 spe_running++; | |
120 } | |
121 } | |
122 } | |
123 | |
124 void | |
808 | 125 CellTaskManagerImpl::poll() |
126 { | |
127 mail_check(); | |
128 // SPE に送る TaskList の準備 | |
129 set_runTaskList(); | |
130 // TaskList 待ちの SPE に TaskList を送る | |
131 sendTaskList(); | |
132 } | |
133 | |
134 void | |
501
7ddbe22d4cdb
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
135 CellTaskManagerImpl::run() |
109 | 136 { |
137 do { | |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
138 // PPE side |
808 | 139 ppeManager->poll(); |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
140 // SPE side |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
141 do { |
808 | 142 poll(); |
854 | 143 } while (ppeManager->activeTaskQueue->empty() && spe_running >0 ); |
144 } while (!ppeManager->activeTaskQueue->empty() || spe_running >0); | |
721 | 145 if (!waitTaskQueue->empty()) { |
736 | 146 get_scheduler()->printf("Dead lock detected\n"); |
721 | 147 } |
70 | 148 } |
149 | |
65 | 150 /** |
321 | 151 * SPE からのメールをチェックする |
640
ecf056ddd21a
SimpeTask on Cell worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
638
diff
changeset
|
152 */ |
ecf056ddd21a
SimpeTask on Cell worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
638
diff
changeset
|
153 |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
154 void |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
155 CellTaskManagerImpl::mail_check() |
57 | 156 { |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
157 memaddr data; |
109 | 158 |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
159 // SPE Scheduler からの mail check |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
160 for (int id = 0; id < machineNum; id++) { |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
161 while (speThreads->has_mail(id, 1, &data)) { |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
162 if (data == (memaddr)MY_SPE_STATUS_READY) { |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
163 // MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 |
853 | 164 // freeAll する前に循環リストに戻す |
165 speTaskList[id]->getLast()->next = speTaskList[id]; | |
808 | 166 speTaskList[id]->freeAll(); |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
167 spe_running--; |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
168 } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) { |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
169 // MY_SPE_COMMAND_MALLOC SPE からのmain memory request |
720 | 170 send_alloc_reply(this, id, speThreads); |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
171 } else if (data > (memaddr)MY_SPE_NOP) { |
830 | 172 #ifdef TASK_LIST_MAIL |
173 TaskListPtr list = (TaskListPtr)data; | |
174 check_task_list_finish(schedTaskManager, list, waitTaskQueue); | |
175 #else | |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
176 // 終了したタスク(PPEにあるのでアドレス) |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
177 HTaskPtr task = (HTaskPtr)data; |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
178 task->post_func(schedTaskManager, task->post_arg1, task->post_arg2); |
830 | 179 check_task_finish(task, waitTaskQueue); |
180 #endif | |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
181 } |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
182 // MY_SPE_NOP: 特に意味のないコマンド |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
183 } |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
184 } |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
185 } |
109 | 186 |
833
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
187 void |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
188 CellTaskManagerImpl::polling() |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
189 { |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
190 // may call recursively check_task_list_finish() |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
191 // we need fifo here |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
192 mail_check(); |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
193 } |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
194 |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
195 static void |
720 | 196 send_alloc_reply(CellTaskManagerImpl *tm, int id, SpeThreads *speThreads) |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
197 { |
275 | 198 |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
199 /** |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
200 * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照) |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
201 * info[1] = alloc_addr; |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
202 */ |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
203 memaddr alloc_info[2]; |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
204 long alloc_size; |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
205 long command; |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
206 |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
207 speThreads->get_mail(id, 2, alloc_info); |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
208 command = (long)alloc_info[0]; |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
209 alloc_size = (long)alloc_info[1]; |
109 | 210 |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
211 |
720 | 212 alloc_info[1] = (memaddr)tm->allocate(alloc_size); |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
213 //__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id); |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
214 // 今のところ何もしてない。どうも、この allocate を free |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
215 // するのは、SPE task が返した値を見て行うらしい。それは、 |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
216 // 忘れやすいのではないか? |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
217 speThreads->add_output_tasklist(command, alloc_info[1], alloc_size); |
109 | 218 |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
219 speThreads->send_mail(id, 2, alloc_info); |
109 | 220 } |
66 | 221 |
109 | 222 /** |
321 | 223 * 条件を満たしたら SPE に TaskList を送信する |
224 * 条件1. SPE が持ってた TaskList を終了して、次の TaskList を待ってる | |
225 * 条件2. SPE に送る TaskList に Task がある | |
109 | 226 * |
808 | 227 * SPE で実行終了した speTaskList と |
228 * これから実行する taskListInfo のバッファを入れ替える | |
109 | 229 */ |
230 void | |
231 CellTaskManagerImpl::send_taskList(int id) | |
232 { | |
808 | 233 if (taskListInfo[id]->empty()) return; |
853 | 234 // speTaskList は走り終わった ppe の Task の List. |
235 // taskListInfo はこれから走る Task の List. | |
236 // 交換して実行する | |
808 | 237 TaskListInfoPtr tmp = taskListInfo[id]; |
238 taskListInfo[id] = speTaskList[id]; | |
239 speTaskList[id] = tmp; | |
109 | 240 |
853 | 241 // speTaskList は本来は循環リストなのだけど、実行中は線形リストである。 |
242 // spe の Task が終了した時点でなおす。 | |
809 | 243 tmp->getLast()->next = 0; |
812 | 244 TaskListPtr p = tmp->getFirst(); |
245 speThreads->send_mail(id, 1, (memaddr *)&p); | |
57 | 246 } |
247 | |
672 | 248 void CellTaskManagerImpl::show_profile() { |
249 for (int id = 0; id < machineNum; id++) { | |
923
382a48afb061
fix DMA/Mail wait profiler
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
897
diff
changeset
|
250 HTaskPtr t = schedTaskManager->create_task(ShowTime,0,0,0,0); |
672 | 251 t->set_cpu((CPU_TYPE)(id+2)); |
252 t->spawn(); | |
253 } | |
254 } | |
255 | |
256 void CellTaskManagerImpl::start_profile() { | |
257 for (int id = 0; id < machineNum; id++) { | |
923
382a48afb061
fix DMA/Mail wait profiler
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
897
diff
changeset
|
258 HTaskPtr t = schedTaskManager->create_task(StartProfile,0,0,0,0); |
672 | 259 t->set_cpu((CPU_TYPE)(id+2)); |
260 t->spawn(); | |
261 } | |
262 } | |
263 | |
380 | 264 |
109 | 265 #ifdef __CERIUM_CELL__ |
57 | 266 TaskManagerImpl* |
267 create_impl(int num) | |
268 { | |
835 | 269 return new CellTaskManagerImpl(num); |
57 | 270 } |
109 | 271 #endif // __CERIUM_CELL |