Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAMPower Library error in calculating intermediate results #31

Closed
myzinsky opened this issue Apr 5, 2016 · 4 comments
Closed

DRAMPower Library error in calculating intermediate results #31

myzinsky opened this issue Apr 5, 2016 · 4 comments

Comments

@myzinsky
Copy link
Member

myzinsky commented Apr 5, 2016

We discovered an issue in the DRAMPower library when intermediate results are needed, e.g. to plot the power consumption over time or if an interactive simulation is conducted. Don't worry, the total energy consumption is still correct.

We do a simulation with DRAMSys and want to plot the current power consumption over time:

bildschirmfoto 2016-04-05 um 09 10 58

at time ~50000 we go into SREF and wake up at ~150000 and we get a big power peak.
in the self refresh time the calculated Energy is 0 and therefore also the current power consumption in the time intervals during SREF.
Obviously the area of this peak should be placed flatted in the interval of the SREF.

This is due to the fact that during the simulation we don’t tell DRAMPower to proceed with the simulation time e.g. during the SREF interval.

I had the idea of a simple workaround:

in our power calculation thread, which is triggered periodically (systemc) I send DRAMPower a NOP function to count up the time:

   ...
   // This Thread is only triggered when Power Simulation is enabled (e.g. every 1us).
   // It estimates the current average power which will be stored in the trace database for visualization purposes.
   void powerWindow()
   {
       double currentAveragePower = 0;
       double currentTotalEnergy = 0;

       do
       {              
            unsigned long long c = sc_time_stamp().value()/Configuration::getInstance().memSpec.clk.value();
            DRAMPower->doCommand(MemCommand::NOP, 0, c);

           DRAMPower->updateCounters(false);
           DRAMPower->calcEnergy();

           currentTotalEnergy = DRAMPower->getEnergy().total_energy - totalEnergy;
           currentAveragePower = currentTotalEnergy/powerWindowSize.value();
           totalEnergy = DRAMPower->getEnergy().total_energy;

           tlmRecorder->recordPower(sc_time_stamp(),currentAveragePower);
           printDebugMessage(string("\tCurrent Energy: \t") + to_string(currentTotalEnergy));
           printDebugMessage(string("\tAverage Power: \t") + to_string(currentAveragePower));

           wait(powerWindowSize);
       }
       while(true);
   }
   ...

However this results in a very strange behavior:

bildschirmfoto 2016-04-05 um 09 09 06

As you can see when we issue multiple NOPs to update the time in DRAM Power, the sref_cycles are accumulating because the beginning of the SREF (sref_cycle) is not updated or reset to the current timestamp.

Lets consider the SREF for now:

CommandAnalysis.cc Line 528

  } else if (type == MemCommand::END || type == MemCommand::NOP) {
      // May be optionally used at the end of memory trace for better accuracy
      // Update all counters based on completion of operations.
      if (num_active_banks > 0 && mem_state == 0) {
        actcycles += max(zero, timestamp - first_act_cycle);
        idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
                        latest_act_cycle, timestamp);
      } else if (num_active_banks == 0 && mem_state == 0) {
        precycles += max(zero, timestamp - last_pre_cycle);
        idle_pre_update(memSpec, timestamp, latest_pre_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_F_ACT) {
        f_act_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) {
        s_act_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_F_PRE) {
        f_pre_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) {
        s_pre_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_SREF) {
        sref_cycles += max(zero, timestamp - sref_cycle); // <—————— this is the possible problem
      }
    }
  }
} // CommandAnalysis::evaluate

We changed the code a little bit below:

  } else if (type == MemCommand::END || type == MemCommand::NOP) {
      // May be optionally used at the end of memory trace for better accuracy
      // Update all counters based on completion of operations.
      if (num_active_banks > 0 && mem_state == 0) {
        actcycles += max(zero, timestamp - first_act_cycle);
        idle_act_update(memSpec, latest_read_cycle, latest_write_cycle,
                        latest_act_cycle, timestamp);
      } else if (num_active_banks == 0 && mem_state == 0) {
        precycles += max(zero, timestamp - last_pre_cycle);
        idle_pre_update(memSpec, timestamp, latest_pre_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_F_ACT) {
        f_act_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_S_ACT) {
        s_act_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_F_PRE) {
        f_pre_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_PDN_S_PRE) {
        s_pre_pdcycles += max(zero, timestamp - pdn_cycle);
      } else if (mem_state == CommandAnalysis::MS_SREF) {
        sref_cycles += max(zero, timestamp - sref_cycle);
        sref_cycle = timestamp; // RESET the sref_cycle
      }
    }
  }
} // CommandAnalysis::evaluate

We did the same for the other power down modes in the else if statements ...
And the result looks like this, which looks much better:

bildschirmfoto 2016-04-05 um 09 20 26

We are currently investigating and testing all the changes and we will come up with a pull request soon.
Moreover, we will adjust the library documentation and the example code.

@Sv3n
Copy link
Collaborator

Sv3n commented Apr 10, 2016

Hi guys, I've received the mail with the zip / patch. I still need to have a look at it (I'm not on my linux laptop now).

@efzulian
Copy link
Contributor

Hi Sven, actually I posted here the patch as a zip file (and some hours later I removed it). It was a mistake, I should have open a proper pull request for that. Please ignore the patch in the zip file for now. We are doing some more tests and as soon we double check everything I will open the pull request.
Thanks!
Éder

@Sv3n
Copy link
Collaborator

Sv3n commented Apr 10, 2016

Ok, no problem. I was already confused a bit, since I couldn't find any reference on github to the mail I received :)

Sv3n added a commit that referenced this issue May 6, 2016
[#31] Intermediate stats generation
@Sv3n
Copy link
Collaborator

Sv3n commented May 7, 2016

I've merged these changes into the master, and merged the mac branch on top of it. We are now back to a single branch from my perspective (master), which has all the latest features.

@Sv3n Sv3n closed this as completed May 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants