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();