34c34,39
< * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji
---
> * Authors: Karthik Chandrasekar
> * Matthias Jung
> * Omar Naji
> * Subash Kannoth
> * Éder F. Zulian
> * Felipe S. Prado
43a49
> #include <algorithm>
45d50
<
48a54,59
> MemoryPowerModel::MemoryPowerModel()
> {
> total_cycles = 0;
> energy.total_energy = 0;
> }
>
53c64,65
< int term)
---
> int term,
> const MemBankWiseParams& bwPowerParams)
57a70
> const int64_t nbrofBanks = memSpec.memArchSpec.nbrOfBanks;
58a72,98
> energy.act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.read_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.write_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.refb_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.act_stdby_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.pre_stdby_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.idle_energy_act_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.idle_energy_pre_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.f_act_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.f_pre_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.s_act_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.s_pre_pd_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.sref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.sref_ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.sref_ref_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.sref_ref_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.spup_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.spup_ref_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.spup_ref_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.spup_ref_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.pup_act_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.pup_pre_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
> energy.total_energy_banks.assign(static_cast<size_t>(nbrofBanks), 0.0);
>
68c108
< energy.total_energy = 0.0;
---
> energy.window_energy = 0.0;
109c149
< energy.read_io_energy = calcIoTermEnergy(c.numberofreads * memArchSpec.burstLength,
---
> energy.read_io_energy = calcIoTermEnergy(sum(c.numberofreadsBanks) * memArchSpec.burstLength,
115c155
< energy.write_term_energy = calcIoTermEnergy(c.numberofwrites * memArchSpec.burstLength,
---
> energy.write_term_energy = calcIoTermEnergy(sum(c.numberofwritesBanks) * memArchSpec.burstLength,
123c163
< energy.read_oterm_energy = calcIoTermEnergy(c.numberofreads * memArchSpec.burstLength,
---
> energy.read_oterm_energy = calcIoTermEnergy(sum(c.numberofreadsBanks) * memArchSpec.burstLength,
130c170
< energy.write_oterm_energy = calcIoTermEnergy(c.numberofwrites * memArchSpec.burstLength,
---
> energy.write_oterm_energy = calcIoTermEnergy(sum(c.numberofwritesBanks) * memArchSpec.burstLength,
141c181
< total_cycles = c.actcycles + c.precycles +
---
> window_cycles = c.actcycles + c.precycles +
149,152c189,192
< energy.act_energy = vdd0Domain.calcTivEnergy(c.numberofacts * t.RAS , mps.idd0 - mps.idd3n);
< energy.pre_energy = vdd0Domain.calcTivEnergy(c.numberofpres * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
< energy.read_energy = vdd0Domain.calcTivEnergy(c.numberofreads * burstCc , mps.idd4r - mps.idd3n);
< energy.write_energy = vdd0Domain.calcTivEnergy(c.numberofwrites * burstCc , mps.idd4w - mps.idd3n);
---
> energy.act_energy = vdd0Domain.calcTivEnergy(sum(c.numberofactsBanks) * t.RAS , mps.idd0 - mps.idd3n);
> energy.pre_energy = vdd0Domain.calcTivEnergy(sum(c.numberofpresBanks) * (t.RC - t.RAS) , mps.idd0 - mps.idd2n);
> energy.read_energy = vdd0Domain.calcTivEnergy(sum(c.numberofreadsBanks) * burstCc , mps.idd4r - mps.idd3n);
> energy.write_energy = vdd0Domain.calcTivEnergy(sum(c.numberofwritesBanks) * burstCc , mps.idd4w - mps.idd3n);
155a196,251
>
> // Using the number of cycles that at least one bank is active here
> // But the current iddrho is less than idd3n
> double iddrho = (static_cast<double>(bwPowerParams.bwPowerFactRho) / 100.0) * (mps.idd3n - mps.idd2n) + mps.idd2n;
> double esharedActStdby = vdd0Domain.calcTivEnergy(c.actcycles, iddrho);
> // Fixed componenent for PASR
> double iddsigma = (static_cast<double>(bwPowerParams.bwPowerFactSigma) / 100.0) * mps.idd6;
> double esharedPASR = vdd0Domain.calcTivEnergy(c.sref_cycles, iddsigma);
> // ione is Active background current for a single bank. When a single bank is Active
> //,all the other remainig (B-1) banks will consume a current of iddrho (based on factor Rho)
> // So to derrive ione we add (B-1)*iddrho to the idd3n and distribute it to each banks.
> double ione = (mps.idd3n + (iddrho * (static_cast<double>(nbrofBanks - 1)))) / (static_cast<double>(nbrofBanks));
> // If memory specification does not provide bank wise refresh current,
> // approximate it to single bank background current removed from
> // single bank active current
> double idd5Blocal = (mps.idd5B == 0.0) ? (mps.idd0 - ione) :(mps.idd5B);
> // if memory specification does not provide the REFB timing approximate it
> // to time of ACT + PRE
> int64_t tRefBlocal = (t.REFB == 0) ? (t.RAS + t.RP) : (t.REFB);
>
> //Distribution of energy componets to each banks
> for (unsigned i = 0; i < nbrofBanks; i++) {
> energy.act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofactsBanks[i] * t.RAS, mps.idd0 - ione);
> energy.pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofpresBanks[i] * (t.RP), mps.idd0 - ione);
> energy.read_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofreadsBanks[i] * burstCc, mps.idd4r - mps.idd3n);
> energy.write_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofwritesBanks[i] * burstCc, mps.idd4w - mps.idd3n);
> energy.ref_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofrefs * t.RFC, mps.idd5 - mps.idd3n) / static_cast<double>(nbrofBanks);
> energy.refb_energy_banks[i] = vdd0Domain.calcTivEnergy(c.numberofrefbBanks[i] * tRefBlocal, idd5Blocal);
> energy.pre_stdby_energy_banks[i] = vdd0Domain.calcTivEnergy(c.precycles, mps.idd2n) / static_cast<double>(nbrofBanks);
> energy.act_stdby_energy_banks[i] = vdd0Domain.calcTivEnergy(c.actcyclesBanks[i], (mps.idd3n - iddrho) / static_cast<double>(nbrofBanks))
> + esharedActStdby / static_cast<double>(nbrofBanks);
> energy.idle_energy_act_banks[i] = vdd0Domain.calcTivEnergy(c.idlecycles_act, mps.idd3n) / static_cast<double>(nbrofBanks);
> energy.idle_energy_pre_banks[i] = vdd0Domain.calcTivEnergy(c.idlecycles_pre, mps.idd2n) / static_cast<double>(nbrofBanks);
> energy.f_act_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.f_act_pdcycles, mps.idd3p1) / static_cast<double>(nbrofBanks);
> energy.f_pre_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.f_pre_pdcycles, mps.idd2p1) / static_cast<double>(nbrofBanks);
> energy.s_act_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.s_act_pdcycles, mps.idd3p0) / static_cast<double>(nbrofBanks);
> energy.s_pre_pd_energy_banks[i] = vdd0Domain.calcTivEnergy(c.s_pre_pdcycles, mps.idd2p0) / static_cast<double>(nbrofBanks);
>
> energy.sref_energy_banks[i] = engy_sref_banks(mps.idd6, mps.idd3n,
> mps.idd5, mps.vdd,
> static_cast<double>(c.sref_cycles), static_cast<double>(c.sref_ref_act_cycles),
> static_cast<double>(c.sref_ref_pre_cycles), static_cast<double>(c.spup_ref_act_cycles),
> static_cast<double>(c.spup_ref_pre_cycles), t.clkPeriod,esharedPASR,bwPowerParams,i,nbrofBanks
> );
> energy.sref_ref_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.sref_ref_act_cycles, mps.idd3p0) / static_cast<double>(nbrofBanks);
> energy.sref_ref_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.sref_ref_pre_cycles, mps.idd2p0) / static_cast<double>(nbrofBanks);
> energy.sref_ref_energy_banks[i] = energy.sref_ref_act_energy_banks[i] + energy.sref_ref_pre_energy_banks[i] ;//
>
> energy.spup_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
> energy.spup_ref_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_ref_act_cycles, mps.idd3n) / static_cast<double>(nbrofBanks);//
> energy.spup_ref_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.spup_ref_pre_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
> energy.spup_ref_energy_banks[i] = ( energy.spup_ref_act_energy + energy.spup_ref_pre_energy ) / static_cast<double>(nbrofBanks);
> energy.pup_act_energy_banks[i] = vdd0Domain.calcTivEnergy(c.pup_act_cycles, mps.idd3n) / static_cast<double>(nbrofBanks);
> energy.pup_pre_energy_banks[i] = vdd0Domain.calcTivEnergy(c.pup_pre_cycles, mps.idd2n) / static_cast<double>(nbrofBanks);
> }
>
196,199c292,295
< energy.act_energy += vdd2Domain.calcTivEnergy(c.numberofacts * t.RAS , mps.idd02 - mps.idd3n2);
< energy.pre_energy += vdd2Domain.calcTivEnergy(c.numberofpres * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
< energy.read_energy += vdd2Domain.calcTivEnergy(c.numberofreads * burstCc , mps.idd4r2 - mps.idd3n2);
< energy.write_energy += vdd2Domain.calcTivEnergy(c.numberofwrites * burstCc , mps.idd4w2 - mps.idd3n2);
---
> energy.act_energy += vdd2Domain.calcTivEnergy(sum(c.numberofactsBanks) * t.RAS , mps.idd02 - mps.idd3n2);
> energy.pre_energy += vdd2Domain.calcTivEnergy(sum(c.numberofpresBanks) * (t.RC - t.RAS) , mps.idd02 - mps.idd2n2);
> energy.read_energy += vdd2Domain.calcTivEnergy(sum(c.numberofreadsBanks) * burstCc , mps.idd4r2 - mps.idd3n2);
> energy.write_energy += vdd2Domain.calcTivEnergy(sum(c.numberofwritesBanks) * burstCc , mps.idd4w2 - mps.idd3n2);
202a299
>
246,251d342
< energy.total_energy = energy.act_energy + energy.pre_energy + energy.read_energy +
< energy.write_energy + energy.ref_energy + energy.io_term_energy +
< static_cast<double>(memArchSpec.nbrOfRanks) * (energy.act_stdby_energy +
< energy.pre_stdby_energy + energy.sref_energy +
< energy.f_act_pd_energy + energy.f_pre_pd_energy + energy.s_act_pd_energy
< + energy.s_pre_pd_energy + energy.sref_ref_energy + energy.spup_ref_energy);
252a344,370
> if (bwPowerParams.bwMode) {
> // Calculate total energy per bank.
> for (unsigned i = 0; i < nbrofBanks; i++) {
> energy.total_energy_banks[i] = energy.act_energy_banks[i] + energy.pre_energy_banks[i] + energy.read_energy_banks[i]
> + energy.ref_energy_banks[i] + energy.write_energy_banks[i] + energy.refb_energy_banks[i]
> + static_cast<double>(memArchSpec.nbrOfRanks) * energy.act_stdby_energy_banks[i]
> + energy.pre_stdby_energy_banks[i] + energy.f_pre_pd_energy_banks[i] + energy.s_act_pd_energy_banks[i]
> + energy.s_pre_pd_energy_banks[i]+ energy.sref_ref_energy_banks[i] + energy.spup_ref_energy_banks[i];
> }
> // Calculate total energy for all banks.
> energy.window_energy = sum(energy.total_energy_banks) + energy.io_term_energy;
>
> } else {
> energy.window_energy = energy.act_energy + energy.pre_energy + energy.read_energy + energy.write_energy
> + energy.ref_energy + energy.io_term_energy + sum(energy.refb_energy_banks)
> + static_cast<double>(memArchSpec.nbrOfRanks) * (energy.act_stdby_energy
> + energy.pre_stdby_energy + energy.sref_energy + energy.f_act_pd_energy
> + energy.f_pre_pd_energy + energy.s_act_pd_energy + energy.s_pre_pd_energy
> + energy.sref_ref_energy + energy.spup_ref_energy);
> }
>
> power.window_average_power = energy.window_energy / (static_cast<double>(window_cycles) * t.clkPeriod);
>
> total_cycles += window_cycles;
>
> energy.total_energy += energy.window_energy;
>
257c375
< void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term, const CommandAnalysis& c) const
---
> void MemoryPowerModel::power_print(const MemorySpecification& memSpec, int term, const CommandAnalysis& c, bool bankwiseMode) const
262a381,382
> const int64_t nbrofBanks = memSpec.memArchSpec.nbrOfBanks;
> double nRanksDouble = static_cast<double>(nRanks);
267,270c387,403
< cout << "* Trace Details:" << fixed << endl
< << endl << "#ACT commands: " << c.numberofacts
< << endl << "#RD + #RDA commands: " << c.numberofreads
< << endl << "#WR + #WRA commands: " << c.numberofwrites
---
>
> if (bankwiseMode) {
> cout << endl << "* Bankwise Details:";
> for (unsigned i = 0; i < nbrofBanks; i++) {
> cout << endl << "## @ Bank " << i << fixed
> << endl << " #ACT commands: " << c.numberofactsBanks[i]
> << endl << " #RD + #RDA commands: " << c.numberofreadsBanks[i]
> << endl << " #WR + #WRA commands: " << c.numberofwritesBanks[i]
> << endl << " #PRE (+ PREA) commands: " << c.numberofpresBanks[i];
> }
> cout << endl;
> }
>
> cout << endl << "* Trace Details:" << fixed << endl
> << endl << "#ACT commands: " << sum(c.numberofactsBanks)
> << endl << "#RD + #RDA commands: " << sum(c.numberofreadsBanks)
> << endl << "#WR + #WRA commands: " << sum(c.numberofwritesBanks)
272c405
< << endl << "#PRE (+ PREA) commands: " << c.numberofpres
---
> << endl << "#PRE (+ PREA) commands: " << sum(c.numberofpresBanks)
273a407
> << endl << "#REFB commands: " << sum(c.numberofrefbBanks)
302a437,468
> if (bankwiseMode) {
> cout << endl << "* Bankwise Details:";
> for (unsigned i = 0; i < nbrofBanks; i++) {
> cout << endl << "## @ Bank " << i << fixed
> << endl << " ACT Cmd Energy: " << energy.act_energy_banks[i] << eUnit
> << endl << " PRE Cmd Energy: " << energy.pre_energy_banks[i] << eUnit
> << endl << " RD Cmd Energy: " << energy.read_energy_banks[i] << eUnit
> << endl << " WR Cmd Energy: " << energy.write_energy_banks[i] << eUnit
> << endl << " Auto-Refresh Energy: " << energy.ref_energy_banks[i] << eUnit
> << endl << " Bankwise-Refresh Energy: " << energy.refb_energy_banks[i] << eUnit
> << endl << " ACT Stdby Energy: " << nRanksDouble * energy.act_stdby_energy_banks[i] << eUnit
> << endl << " PRE Stdby Energy: " << nRanksDouble * energy.pre_stdby_energy_banks[i] << eUnit
> << endl << " Active Idle Energy: "<< nRanksDouble * energy.idle_energy_act_banks[i] << eUnit
> << endl << " Precharge Idle Energy: "<< nRanksDouble * energy.idle_energy_pre_banks[i] << eUnit
> << endl << " Fast-Exit Active Power-Down Energy: "<< nRanksDouble * energy.f_act_pd_energy_banks[i] << eUnit
> << endl << " Fast-Exit Precharged Power-Down Energy: "<< nRanksDouble * energy.f_pre_pd_energy_banks[i] << eUnit
> << endl << " Slow-Exit Active Power-Down Energy: "<< nRanksDouble * energy.s_act_pd_energy_banks[i] << eUnit
> << endl << " Slow-Exit Precharged Power-Down Energy: "<< nRanksDouble * energy.s_pre_pd_energy_banks[i] << eUnit
> << endl << " Self-Refresh Energy: "<< nRanksDouble * energy.sref_energy_banks[i] << eUnit
> << endl << " Slow-Exit Active Power-Down Energy during Auto-Refresh cycles in Self-Refresh: "<< nRanksDouble * energy.sref_ref_act_energy_banks[i] << eUnit
> << endl << " Slow-Exit Precharged Power-Down Energy during Auto-Refresh cycles in Self-Refresh: " << nRanksDouble * energy.sref_ref_pre_energy_banks[i] << eUnit
> << endl << " Self-Refresh Power-Up Energy: "<< nRanksDouble * energy.spup_energy_banks[i] << eUnit
> << endl << " Active Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "<< nRanksDouble * energy.spup_ref_act_energy_banks[i] << eUnit
> << endl << " Precharge Stdby Energy during Auto-Refresh cycles in Self-Refresh Power-Up: "<< nRanksDouble * energy.spup_ref_pre_energy_banks[i] << eUnit
> << endl << " Active Power-Up Energy: "<< nRanksDouble * energy.pup_act_energy_banks[i] << eUnit
> << endl << " Precharged Power-Up Energy: "<< nRanksDouble * energy.pup_pre_energy_banks[i] << eUnit
> << endl << " Total Energy: "<< energy.total_energy_banks[i] << eUnit
> << endl;
> }
> cout << endl;
> }
>
311c477
< cout << "RD I/O Energy: " << energy.read_io_energy << eUnit << endl;
---
> cout << endl << "RD I/O Energy: " << energy.read_io_energy << eUnit << endl;
323,324d488
< double nRanksDouble = static_cast<double>(nRanks);
<
342a507
> << endl << "Bankwise-Refresh Energy: " << sum(energy.refb_energy_banks) << eUnit
366a532,576
> // Self-refresh active energy estimation per banks
> double MemoryPowerModel::engy_sref_banks(double idd6, double idd3n, double idd5,
> double vdd, double sref_cycles, double sref_ref_act_cycles,
> double sref_ref_pre_cycles, double spup_ref_act_cycles,
> double spup_ref_pre_cycles, double clk,
> double esharedPASR, const MemBankWiseParams& bwPowerParams,
> unsigned bnkIdx, int64_t nbrofBanks)
> {
> // Bankwise Self-refresh energy
> double sref_energy_banks;
> // Dynamic componenents for PASR energy varying based on PASR mode
> double iddsigmaDynBanks;
> double pasr_energy_dyn;
> // This component is distributed among all banks
> double sref_energy_shared;
> //Is PASR Active
> if (bwPowerParams.flgPASR){
> sref_energy_shared = (((idd5 - idd3n) * (sref_ref_act_cycles
> + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)) * vdd * clk)
> / static_cast<double>(nbrofBanks);
> //if the bank is active under current PASR mode
> if (bwPowerParams.isBankActiveInPasr(bnkIdx)){
> // Distribute the sref energy to the active banks
> iddsigmaDynBanks = (static_cast<double>(100 - bwPowerParams.bwPowerFactSigma) / (100.0 * static_cast<double>(nbrofBanks))) * idd6;
> pasr_energy_dyn = vdd * iddsigmaDynBanks * sref_cycles;
> // Add the static components
> sref_energy_banks = sref_energy_shared + pasr_energy_dyn + (esharedPASR /static_cast<double>(nbrofBanks));
>
> }else{
> sref_energy_banks = (esharedPASR /static_cast<double>(nbrofBanks));
> }
> }
> //When PASR is not active total all the banks are in Self-Refresh. Thus total Self-Refresh energy is distributed across all banks
> else{
>
>
> sref_energy_banks = (((idd6 * sref_cycles) + ((idd5 - idd3n) * (sref_ref_act_cycles
> + spup_ref_act_cycles + sref_ref_pre_cycles + spup_ref_pre_cycles)))
> * vdd * clk)
> / static_cast<double>(nbrofBanks);
> }
> return sref_energy_banks;
> }
>
>
399a610
>