Mercurial > hg > Game > Cerium
view TaskManager/Cell/spe/MemIterator.cc @ 2054:2e7a6f40672f draft
add param(4) in FileMapReduce.cc
author | masa |
---|---|
date | Fri, 29 Jan 2016 15:56:28 +0900 |
parents | 0094cd28bf41 |
children |
line wrap: on
line source
#include "MemIterator.h" /* * Iterator は MemList にまとめる方がいいかも。 * * @param [addr_list] main memory 側のアドレスリスト * @param [mem_list] memory segment のリスト * @param [cmd] Iterator パターンというべきか. * * cmd は、ms, MemList で情報を持っててもできる * */ 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 = 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 = 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 = addr_list->next; return write_ms; } /* * 出しておいた segment 命令を待つ. * まだ、書きこまれていないmsを書きこむ * 最後の締め. */ void MemIterator::collect_ms(void) { smanager->put_segment(write_ms); smanager->wait_segment(free_ms); smanager->wait_segment(write_ms); smanager->wait_segment(read_ms); } /* * 走査中のlistの一部を上書きする. * mainMem (CreateSpan) とかやるとき、使う予定 */ void MemIterator::overwrite_list(AddrListPtr list) { /* * すでに次のリストの read を開始している可能性がある * ので、それをいったん中止、同じ ms に 新しく load をかける。 * * でも、これは write only な場合いらない.. */ // dma命令キャンセルする方法があるかな. 調べてみる. あるならwaitするよりそっちがいい. smanager->wait_segment(read_ms); /* segment に直接上書きする機能が必要かも. 要実装. * 指定した ms に load する * この場合は、read_ms に新しく list->addr を load する */ smanager->overwrite_segment(read_ms, list->addr); /* * 現在のaddr_list を新しい list に上書きする */ AddrListPtr tmp = list; while(list->next) { list = list->next; } list->next = addr_list->next; addr_list = tmp; }