Mercurial > hg > Game > Cerium
changeset 1173:cce350bed940 draft
add MemIterator. (no test)
author | Yutaka_Kinjyo |
---|---|
date | Tue, 07 Jun 2011 01:22:42 +0900 |
parents | 614562ada648 |
children | 0e826d18f59a |
files | Renderer/Engine/SpanPack.h Renderer/Engine/task/CreateSpan.cc TaskManager/kernel/memory/AddrList.h TaskManager/kernel/memory/MemIterator.cc TaskManager/kernel/memory/MemIterator.h TaskManager/kernel/schedule/SchedTask.cc TaskManager/kernel/schedule/SchedTask.h TaskManager/kernel/schedule/Scheduler.cc TaskManager/kernel/schedule/Scheduler.h |
diffstat | 9 files changed, 277 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Renderer/Engine/SpanPack.h Sun Jun 05 17:59:02 2011 +0900 +++ b/Renderer/Engine/SpanPack.h Tue Jun 07 01:22:42 2011 +0900 @@ -4,7 +4,7 @@ #include "Span.h" #define MAX_SIZE_SPAN 64 -#define SPANPACK_SEGMENT_NUM 2 +#define SPANPACK_SEGMENT_NUM 4 class SpanPack { public: /* fields */
--- a/Renderer/Engine/task/CreateSpan.cc Sun Jun 05 17:59:02 2011 +0900 +++ b/Renderer/Engine/task/CreateSpan.cc Tue Jun 07 01:22:42 2011 +0900 @@ -388,6 +388,7 @@ /** * 担当 y 範囲内 + * 必要なデータは先読みできるはず */ if (charge_y_top <= y && y <= charge_y_end) { // 1..8 を index0, 9..16 を index1 にするために y を -1 @@ -403,6 +404,13 @@ #ifdef USE_SEGMENT + /* + it = create_iterator(spackList, span_ml); + ms = (MemorySegmentPtr)it->get_ms(); + spack = (SpanPackPtr)ms->data; + + */ + smanager->wait_segment(span_put_ms); span_put_ms = span_get_ms; @@ -446,6 +454,7 @@ * Segment領域を確保して、それをsegmentのAPIでやり取りするのが嬉しいのかね。 * * mainMem 追い出すには、ちょっと苦労するかも? + * mainMem するかどうかは予想できる。 */ if (spack->info.size >= MAX_SIZE_SPAN) { @@ -460,6 +469,12 @@ #ifdef USE_SEGMENT + /* + cur_spack = get_list_cur(); + cur_spack = next; + + */ + smanager->wait_segment(span_put_ms); span_put_ms = span_get_ms;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/memory/AddrList.h Tue Jun 07 01:22:42 2011 +0900 @@ -0,0 +1,20 @@ +#ifndef INCLUDED_ADDR_LIST +#define INCLUDED_ADDR_LIST + +#include "types.h" + +/* + + MainMemory 側の MemorySegment に近いかも? + Iterator で使う、MainMemory 側の アドレスリスト + + */ + +typedef struct AddrList { + + memaddr addr; + memaddr next; + +}AddrList, *AddrListPtr; // 8 + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/memory/MemIterator.cc Tue Jun 07 01:22:42 2011 +0900 @@ -0,0 +1,153 @@ +#include "MemIterator.h" + +/* + * Iterator は MemList にまとめる方がいいかも。 + * + * @param [addr_list] main memory 側のアドレスリスト + * @param [mem_list] memory segment のリスト + * @param [cmd] Iterator パターンというべきか. + */ + +MemIterator::MemIterator(AddrListPtr addr_list, MemList *mem_list, + int cmd, SchedTask *smanager) +{ + + this->addr_list = addr_list; + this->mem_list = mem_list; + this->smanager = smanager; + + read_ms = NULL; + exec_ms = NULL; + write_ms = NULL; + free_ms = NULL; + + // コマンドは、ms 自体に持たせるべきなのかも知れない。 + + if (cmd == READ_WRITE) { + + // 始め、必要になるであろう、データを load しておく + read_ms = smanager->get_segment(addr_list->addr,mem_list); + get_ms = &MemIterator::get_read_write_ms; + + } else if (cmd == READ) { + + // 始め、必要になるであろう、データを load しておく + read_ms = smanager->get_segment(addr_list->addr,mem_list); + get_ms = &MemIterator::get_read_ms; + + } else if(cmd == WRITE) { + + get_ms = &MemIterator::get_write_ms; + + } + + +} + +/* + * 次の ms があるか返す + * + * @retval 1 next がある + * @retval 0 next がない + */ +int +MemIterator::hasNext(void) +{ + return (addr_list->next) ? 1 : 0; +} + +/* + * アドレスのリストから次に使う領域は予想できる + * read, write する ms に使う。 + * + * @return アドレスのリストに沿って、msに格納し返す + */ +MemorySegmentPtr +MemIterator::get_read_write_ms(void) +{ + + // main memory に書き出し + smanager->put_segment(write_ms); + + /* + * 前回の put segment を待つ + * ms はメモリ領域を使い回しているので、free 部分も dma 完了を待つ + */ + smanager->wait_segment(free_ms); + + // stage 遷移 + free_ms = write_ms; + write_ms = exec_ms; + exec_ms = read_ms; + + // アドレスをリストから追っていく + addr_list = (AddrListPtr)addr_list->next; + + // 次必要なものを load し始めておく + read_ms = smanager->get_segment(addr_list->addr, mem_list); + + + // 前回の get segment を待つ + smanager->wait_segment(exec_ms); + + return exec_ms; +} + +/* + * read only な ms に使う + * + * @return アドレスのリストに沿って、msに格納し返す + */ +MemorySegmentPtr +MemIterator::get_read_ms(void) +{ + + // stage 遷移 + exec_ms = read_ms; + + // アドレスをリストから追っていく + addr_list = (AddrListPtr)addr_list->next; + + + // 次必要なものを load し始めておく + read_ms = smanager->get_segment(addr_list->addr,mem_list); + + // 前回の get segment を待つ + smanager->wait_segment(exec_ms); + + return exec_ms; +} + +/* + * アドレスのリストから次に使う領域は予想できる + * write only な ms に使うパターン + * + * @return free な ms 領域を返す + */ +MemorySegmentPtr +MemIterator::get_write_ms(void) +{ + + /* + * 前回の put segment を待つ. + * ms はメモリ領域を使い回しているので、free 部分も dma 完了を待つ. + * 書き出しのタイミングは memory segment の数による + * ので、最適な書き込み完了待ちはできない. + * MemList 側に書けば、できるはず. + */ + smanager->wait_segment(free_ms); + + // stage 遷移 + free_ms = write_ms; + + // 書きこみ開始。次 get_write_ms が呼ばれる時に wait する。 + smanager->put_segment(free_ms); + + // free な領域を取得する。dma load する必要はない。 + write_ms = smanager->get_free_segment(addr_list->addr, mem_list); + + // アドレスをリストから追っていく + addr_list = (AddrListPtr)addr_list->next; + + return write_ms; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/memory/MemIterator.h Tue Jun 07 01:22:42 2011 +0900 @@ -0,0 +1,46 @@ +#ifndef INCLUDED_MEMORY_ITERATOR +#define INCLUDED_MEMORY_ITERATOR + +#include "MemList.h" +#include "MemorySegment.h" +#include "AddrList.h" +#include "SchedTask.h" + +enum { + + READ_WRITE, + READ, + WRITE, + +}; + +class MemIterator { +public: + + // 走査する アドレスリスト + AddrListPtr addr_list; + + // 扱う MemorySegment のリスト + MemList *mem_list; + + // ms の stage + MemorySegmentPtr read_ms; + MemorySegmentPtr exec_ms; + MemorySegmentPtr write_ms; + MemorySegmentPtr free_ms; + + SchedTask *smanager; + + MemIterator(AddrListPtr add_list, MemList *mem_list, int cmd, SchedTask *smanager); + ~MemIterator(); + + int hasNext(void); + MemorySegmentPtr (MemIterator::*get_ms)(void); + MemorySegmentPtr get_read_write_ms(void); + MemorySegmentPtr get_read_ms(void); + MemorySegmentPtr get_write_ms(void); +}; + +typedef MemIterator *MemIteratorPtr; + +#endif
--- a/TaskManager/kernel/schedule/SchedTask.cc Sun Jun 05 17:59:02 2011 +0900 +++ b/TaskManager/kernel/schedule/SchedTask.cc Tue Jun 07 01:22:42 2011 +0900 @@ -266,6 +266,11 @@ return scheduler->get_segment(addr,m); } +MemorySegment * SchedTask::get_free_segment(memaddr addr, MemList *m) { + return scheduler->get_free_segment(addr,m); +} + + void SchedTask::put_segment(MemorySegment *s) { scheduler->put_segment(s); }
--- a/TaskManager/kernel/schedule/SchedTask.h Sun Jun 05 17:59:02 2011 +0900 +++ b/TaskManager/kernel/schedule/SchedTask.h Tue Jun 07 01:22:42 2011 +0900 @@ -65,6 +65,7 @@ memaddr mainMem_get(int id); MemorySegment * get_segment(memaddr addr, MemList *m); + MemorySegment * get_free_segment(memaddr addr, MemList *m); uint32 get_tag(); void put_segment(MemorySegment *s); void wait_segment(MemorySegment *s);
--- a/TaskManager/kernel/schedule/Scheduler.cc Sun Jun 05 17:59:02 2011 +0900 +++ b/TaskManager/kernel/schedule/Scheduler.cc Tue Jun 07 01:22:42 2011 +0900 @@ -421,6 +421,38 @@ } +/*! + + free な Segmentを取得する(SPEのLSから) + 書き込み専用の場合、dma_loadは必要ないので + こういう感じになるのかな. + + @param [addr] Main Memory のアドレス + @param [m] Mem List + @return allocate した領域のポインタ + memory directory にあるべきだが... + + */ + +MemorySegment * +Scheduler::get_free_segment(memaddr addr, MemList *m) +{ + + + if(addr == NULL) { + return NULL; + } + + MemorySegment *s = m->getLast(); + m->moveToFirst(s); + s->tag = get_tag(); + s->address = addr; + + return s; + +} + + MemorySegment * Scheduler::get_segment(memaddr addr, MemList *m, int size) { @@ -457,6 +489,8 @@ } + + uint32 Scheduler::get_tag() {
--- a/TaskManager/kernel/schedule/Scheduler.h Sun Jun 05 17:59:02 2011 +0900 +++ b/TaskManager/kernel/schedule/Scheduler.h Tue Jun 07 01:22:42 2011 +0900 @@ -110,6 +110,8 @@ MemorySegment * get_segment(memaddr addr, MemList *m); MemorySegment * get_segment(memaddr addr, MemList *m, int size); + MemorySegment * get_free_segment(memaddr addr, MemList *m); + void allocate_code_segment(int size, int count,struct tbl *table); virtual uint32 get_tag();