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;

}