20151117

1. Power Consumption Model 관련 조사
– CACTI는 작은 크기의 구조에 대해 power model이 정확하지 않고, technology에 민감하다.
– [ISCA’00] Wattch: a framework for architectural-level power analysis and optimizations
Power-Aware Branch Prediction: Characterization and Design에서 power consumption을 측정하기 위해 Wattch를 사용함.
– [ICCD’02] Branch Predictor Prediction: A Power-Aware Branch Predictor for HighPerformance Processors에서 Wattch를 사용함.
– 그 외의 다양한 branch predictor 관련 연구에서도 Wattch를 사용함.
– McPAT simulator도 power modeling simulator이다. 추가로 timing과 area를 고려한다는 점, dynamic power 외에 short-circuit power, static power를 고려한다는 점, non-linear scaling model을 사용한다는 점에서 차이가 있다고 한다[1].

References:
[1] Wattch, http://www.eecs.harvard.edu/~dbrooks/wattch-form.html
[2] McPAT : An Intefrated Power, Area, and Timing Modeling Framework for Multicore and Manycore Architectures, http://jmanbal.tistory.com/entry/McPAT-An-Intefrated-Power-Area-and-Timing-Modeling-Framework-for-Multicore-and-Manycore-Architectures
[3] McPAT, HP labs, http://www.hpl.hp.com/research/mcpat/


2. McPAT 소스 코드 분석
– Power model simulator 중 Wattch가 그동안 많이 쓰임. 논문 인용 횟수도 2927회에 달함. 하지만 Wattch가 SimpleScalar simulator에 붙어있어 사용하기가 까다롭다는 단점이 있다. McPAT은 독립적으로 실행 가능하며, 전력 소모 모델링이 더 상세하다. McPAT은 XML 기반의 processor description을 주면 power consumption을 알려준다. McPAT 소스 코드를 분석해 봄. mercurial을 사용해 McPAT을 다운받을 수 있다.

$hg clone https://code.google.com/p/mcpat/

– main.cc가 McPAT의 main 함수를 갖고 있음. main 함수에서는 XML file을 parsing하여 각종 인자값을 초기화한 다음, Processor를 생성해 전력 소모를 출력한다.

int main(int argc,char *argv[])
{
 ...
    //parse XML-based interface
    ParseXML *p1= new ParseXML();
    p1->parse(fb);
    Processor proc(p1);
    proc.displayEnergy(2, plevel);
    delete p1; 
    return 0;
}

– main.cc의 main 함수에서 XML 파일을 파싱하기 위해 ParseXML이라는 클래스의 객체를 생성한 다음, parse()를 호출한다. parse()함수에서 McPAT의 변수를 초기화한다. parse() 함수는 XML_Parse.cc에 정의되어 있으며, sys 객체를 초기화한다. sys 객체가 시스템에 대한 변수들을 담고 있다. sys는 구조체 객체이며, root_system 타입으로 재선언되어 있음. 코어의 수, L1 directory의 수 등을 갖고 있다. 추가하고자 하는 변수가 있다면 XML_Parse.h의 구조체를 변경해야 한다. root_system에 새로운 변수를 추가하면 됨.

typedef struct{
    //All number_of_* at the level of 'system' Ying 03/21/2009
    int number_of_cores;
    int number_of_L1Directories;
...
    system_niu niu;
    system_pcie pcie;
} root_system;

– 이렇게 초기화된 변수는 Processor 객체의 set_proc_param 함수에서 받아간다. set_proc_param 함수에서 XML parser에서 초기화한 변수 값을 Processor로 복사한다.

void Processor::set_proc_param()
{
    bool debug = false;

    procdynp.homoCore = bool(debug?1:XML->sys.homogeneous_cores);
    procdynp.homoL2   = bool(debug?1:XML->sys.homogeneous_L2s);
    procdynp.homoL3   = bool(debug?1:XML->sys.homogeneous_L3s);
    procdynp.homoNOC  = bool(debug?1:XML->sys.homogeneous_NoCs);
    procdynp.homoL1Dir  = bool(debug?1:XML->sys.homogeneous_L1Directories);
    procdynp.homoL2Dir  = bool(debug?1:XML->sys.homogeneous_L2Directories);
...
    interface_ip.force_wiretype      = false;
    interface_ip.print_detail        = 1;
    interface_ip.add_ecc_b_          =true;
}

– Processor 객체가 전력 소모의 최상위 객체이다. Processor 내부에서 필요로 하는 모든 객체를 생성하고, 관련 정보를 Componenet 객체에 유지한다. component 객체는 전력 소모량, 사용 면적 등의 정보를 갖는다. Processor 객체는 필요로 하는 객체들을 순차적으로 생성하고, 차례대로 area, power 등을 더해 나간다. Processor 객체가 생성하는 Component 객체에는 Core, SharedCache, MemoryController, NoC 등이 있다.

  for (i = 0;i < numCore; i++)
  {
          cores.push_back(new Core(XML,i, &interface_ip));
          cores[i]->computeEnergy();
          cores[i]->computeEnergy(false);
          if (procdynp.homoCore){
              core.area.set_area(core.area.get_area() + cores[i]->area.get_area()*procdynp.numCore);
              set_pppm(pppm_t,cores[i]->clockRate*procdynp.numCore, procdynp.numCore,procdynp.numCore,procdynp.numCore);
              core.power = core.power + cores[i]->power*pppm_t;
              set_pppm(pppm_t,1/cores[i]->executionTime, procdynp.numCore,procdynp.numCore,procdynp.numCore);
              core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t;
              area.set_area(area.get_area() + core.area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm
              power = power  + core.power;
              rt_power = rt_power  + core.rt_power;
          }   
          else{
              core.area.set_area(core.area.get_area() + cores[i]->area.get_area());
              area.set_area(area.get_area() + cores[i]->area.get_area());//placement and routing overhead is 10%, core scales worse than cache 40% is accumulated from 90 to 22nm

              set_pppm(pppm_t,cores[i]->clockRate, 1, 1, 1); 
              core.power = core.power + cores[i]->power*pppm_t;
              power = power  + cores[i]->power*pppm_t;

              set_pppm(pppm_t,1/cores[i]->executionTime, 1, 1, 1); 
              core.rt_power = core.rt_power + cores[i]->rt_power*pppm_t;
              rt_power = rt_power  + cores[i]->rt_power*pppm_t;
          }   
  }

– 각 객체도 내부적으로 계층적인 구조를 갖는다. Core는 초기화되는 시점에서 InstFetchU, LoadStoreU, MemManU, EXECU, UndiffCore 등의 객체를 생성하고 초기화한다.

Core::Core(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_)
:XML(XML_interface),
 ithCore(ithCore_),
 interface_ip(*interface_ip_),
 ifu  (0),
 lsu  (0), 
 mmu  (0), 
 exu  (0), 
 rnu  (0), 
 corepipe (0),
 undiffCore (0),
 l2cache (0)
{
 /*
  * initialize, compute and optimize individual components.
  */

  bool exit_flag = true;

  double pipeline_area_per_unit;
  //  interface_ip.wire_is_mat_type = 2;
  //  interface_ip.wire_os_mat_type = 2;
  //  interface_ip.wt               =Global_30;
  set_core_param();

  if (XML->sys.Private_L2)
  {
      l2cache = new SharedCache(XML,ithCore, &interface_ip);

  }

  clockRate = coredynp.clockRate;
  executionTime = coredynp.executionTime;
  ifu          = new InstFetchU(XML, ithCore, &interface_ip,coredynp,exit_flag);
  lsu          = new LoadStoreU(XML, ithCore, &interface_ip,coredynp,exit_flag);
  mmu          = new MemManU   (XML, ithCore, &interface_ip,coredynp,exit_flag);
  exu          = new EXECU     (XML, ithCore, &interface_ip,lsu->lsq_height, coredynp,exit_flag);
  undiffCore   = new UndiffCore(XML, ithCore, &interface_ip,coredynp,exit_flag);
  if (coredynp.core_ty==OOO)
  {
      rnu = new RENAMINGU(XML, ithCore, &interface_ip,coredynp);
  }
  corepipe = new Pipeline(&interface_ip,coredynp);

– 따라서 새로운 구조를 추가해 전력을 측정하려면, 우선 필요한 변수를 root_system 구조체에 추가해야 한다. 그리고 이를 읽어오고 초기화하는 루틴을 수정해야 한다. XML_Parse.cc의 parse 함수를 수정해, XML을 읽어오는 부분을 수정해야 한다. 그리고 Processor.cc의 set_proc_param 함수를 수정해, Processor 내부 변수가 초기화될 수 있도록 해주어야 한다. 그리고 적절한 지점에서 객체 생성 루틴과 computeEnergy 루틴을 추가한다. 그 외에, area 관련 코드도 수정하여 area를 반영할 수 있도록 한다.
– 한편 어려운 점은 어떻게 computeEnergy 함수를 구성할 것인지, 어떤 변수가 필요한지, 전력과 변수들의 관계는 어떻게 되는지 등이다.

References:
[1] McPAT: An integrated power, area, and timing modeling framework for multicore and manycore architectures, http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=5375438&tag=1
[2] McPAT, HP Labs, http://www.hpl.hp.com/research/mcpat/
[3] McPAT, https://code.google.com/p/mcpat/

Advertisements
Tagged with: , , , , , , , , , , , , , , , , , , , , ,
Posted in 1) Memo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

누적 방문자 수
  • 101,234 hits
%d bloggers like this: