view TaskManager/Cell/spe/CellDmaManager.cc @ 672:3b6290c05f9f

add profiling code
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 05 Dec 2009 20:20:08 +0900
parents 7c9ded1ea750
children 45ddb28c592d
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include "CellDmaManager.h"



/**
 * DMA Load
 *
 * @param[in] buf  Buffer of Load Data
 * @param[in] addr Address of Load Data at Main Memory
 * @param[in] size Size of Load Data
 * @param[in] mask DMA tag
*/
void CellDmaManager::dma_load(void *buf, memaddr addr, uint32 size, uint32 mask)
{
    if (size == 0) return ;
    mfc_get((volatile void *)buf, addr, size, mask, 0, 0);
}

/**
 * DMA Store
 *
 * @param[in] buf  Buffer of Store Data at SPE
 * @param[in] addr Address of Store Data at Main Memory
 * @param[in] size Size of Store Data
 * @param[in] mask DMA tag
*/
void CellDmaManager::dma_store(void *buf, memaddr addr, uint32 size, uint32 mask)
{
    if (size == 0) return ;
    mfc_put((volatile void *)buf, addr, size, mask, 0, 0);
}

void CellDmaManager::dma_wait(uint32 mask)
{
    (this->*start_dmawait_profile)();
    mfc_write_tag_mask(1 << mask);
    mfc_write_tag_update_all();
    mfc_read_tag_status();
    (this->*end_dmawait_profile)();
}

void CellDmaManager::mail_write(memaddr data)
{
    (this->*start_dmawait_profile)();
    spu_write_out_mbox((uint32)data);
    if (ABIBIT>32) {
	unsigned long data0 = (unsigned long)data;
	spu_write_out_mbox((uint32)(data0>>4));
    }
    (this->*end_dmawait_profile)();
}

memaddr CellDmaManager::mail_read()
{
    (this->*start_dmawait_profile)();
    memaddr data = (memaddr)spu_read_in_mbox();
    if (ABIBIT>32) {
	data += (spu_read_in_mbox()<<4);
    }
    (this->*end_dmawait_profile)();
    return data;
}

void CellDmaManager::dma_loadList(ListDataPtr list, void *buff, uint32 mask)
{
    mfc_getl(buff, 0, list->element, sizeof(mfc_list_element_t)*list->length,
	     mask, 0, 0);
}

void CellDmaManager::dma_storeList(ListDataPtr list, void *buff, uint32 mask)
{
    mfc_putl(buff, 0, list->element, sizeof(mfc_list_element_t)*list->length,
	     mask, 0, 0);
}


CellDmaManager::CellDmaManager() 
{
    stop_profile();
}

void
CellDmaManager::start_profile()
{
    start_dmawait_profile =  &CellDmaManager::do_start_dmawait_profile;
    end_dmawait_profile =  &CellDmaManager::do_end_dmawait_profile;
}

void
CellDmaManager::stop_profile()
{
    start_dmawait_profile =  &CellDmaManager::null_start_dmawait_profile;
    end_dmawait_profile =  &CellDmaManager::null_end_dmawait_profile;
}

/**
 * DMA Wait
 *
 * @param[in] mask Tag for Wait DMA process
 */
void
CellDmaManager::do_start_dmawait_profile()
{
    wait_time = spu_readch(SPU_RdDec); 
    global_busy_time += busy_time - wait_time;
    spu_writech(SPU_WrDec, 0xffffffff);
}

void
CellDmaManager::do_end_dmawait_profile()
{
    wait_time = spu_readch(SPU_RdDec);
    global_wait_time += 0xffffffff - wait_time;
    busy_time = wait_time;
}

void CellDmaManager::null_start_dmawait_profile() {}
void CellDmaManager::null_end_dmawait_profile() {}

void
CellDmaManager::show_dma_wait(int cpu)
{

  printf("spu%d: global_wait_time = %lld\n",cpu, global_wait_time);
  printf("spu%d: global_busy_time = %lld\n",cpu, global_busy_time);
  printf("spu%d: busy_ratio = %g%%\n",cpu, 
	 ((double)global_busy_time)/((double)(global_busy_time+global_wait_time))*100.0);
}


/* end */