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

Added GPU-CA On time tracking & idle time reaction #2841

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from

Conversation

lhlawson
Copy link
Contributor

@lhlawson lhlawson commented Feb 8, 2023

Signed-off-by: lhlawson lowren.h.lawson@intel.com

Provides a report entry for tracking the GPU energy usage when the GPU is above a utilization threshold.
Provides an algorithm update to target long idle periods.

src/GPUActivityAgent.cpp Outdated Show resolved Hide resolved
}
}
else {
m_gpu_idle_timer.at(domain_idx) = 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The width of the idle filter should probably be calculated or at least #defined close to the agent's wait time in case wait time becomes variable in the future

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That comment assumes this is supposed to approximate a time-based filter. If it is actually meant to be 10 samples regardless of time, then also add a comment explaining why.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to a define of 10 samples regardless of time requested, with a comment explaining why.

@lhlawson lhlawson added the 3.0 label Jul 28, 2023
@lhlawson lhlawson marked this pull request as ready for review September 21, 2023 23:31
@@ -138,6 +150,8 @@ namespace geopm
m_gpu_freq_max_control.push_back(m_control{m_platform_io.push_control("GPU_CORE_FREQUENCY_MAX_CONTROL",
m_agent_domain,
domain_idx), NAN});
m_gpu_idle_timer.push_back(10);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
m_gpu_idle_timer.push_back(10);
m_gpu_idle_timer.push_back(IDLE_SAMPLE_COUNT);

Comment on lines 26 to 31
// IDLE SAMPLE COUNT of 10 is based upon a study of the idle behavior of CORAL-2
// workloads of interest assuming the default 20ms sample rate (200ms idle).
// We could use 200ms as the default for the agent, but this does not provide a
// mechanism for user control of the idle period. Using a count provides partial
// user control in that the idleness period is defined by the requested agent
// control loop time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes it sound like the goal is actually time-based rather than sample-based. Should IDLE_SAMPLE_COUNT be computed from environment().period(M_WAIT_SEC) and a 200ms target instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ideal solution would be to provide a control for both the control loop time (via waiter) and the idle time until the agent takes action. We don't currently have the agent built with this in mind, so having the idle time be a function of the user input we do have seemed preferable as there could be a workload that has the behavior
... N milliseconds active, 200 ms idle, N milliseconds active ...
We can either:

  1. Make it sample based, giving the user some control
  2. Make it time based, and risk a pathological case described above
  3. Add the idle time/sample count to the policy

Of these I like either 1 or 2

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a #define instead of a const like M_CPU_ACTIVITY_CUTOFF and set in initializer list?

If we expect this is something the user would modify, it should be a policy parameter.

lhlawson and others added 10 commits September 28, 2023 10:14
Signed-off-by: lhlawson <lowren.h.lawson@intel.com>
Co-authored-by: Daniel Wilson <daniel.wilsonboy@gmail.com>
…ve time

Signed-off-by: lhlawson <lowren.h.lawson@intel.com>
Signed-off-by: lhlawson <lowren.h.lawson@intel.com>
Signed-off-by: lhlawson <lowren.h.lawson@intel.com>
Signed-off-by: lhlawson <lowren.h.lawson@intel.com>
Signed-off-by: lhlawson <lowren.h.lawson@intel.com>
Signed-off-by: Lowren Lawson <lowren.h.lawson@intel.com>
Signed-off-by: Lowren Lawson <lowren.h.lawson@intel.com>
Signed-off-by: Lowren Lawson <lowren.h.lawson@intel.com>
… requirements

Signed-off-by: Lowren Lawson <lowren.h.lawson@intel.com>
@lhlawson
Copy link
Contributor Author

  • Prior to merge the GPU-CA should be re-run with all review fixes on the target hardware with one workload of interest.

Copy link
Contributor

@bgeltz bgeltz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration test(s)?

Comment on lines 54 to 58
If a ``phi`` value of 0.5 or greater is used and a long idle period, defined as
10 samples with a ``GPU_UTILIZATION`` of 0, occurs the agent will request the
minimum frequency for GPU as specified by the ``GPU_CORE_FREQUENCY_MIN_AVAIL``
signal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this paragraph belongs up with the other discussion of the phi policy parameter (one paragraph up).

@@ -23,6 +23,14 @@
#include "Waiter.hpp"
#include "Environment.hpp"

// IDLE SAMPLE COUNT of 10 is based upon a study of the idle behavior of CORAL-2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// IDLE SAMPLE COUNT of 10 is based upon a study of the idle behavior of CORAL-2
// IDLE_SAMPLE_COUNT of 10 is based upon a study of the idle behavior of CORAL-2

if (!std::isnan(gpu_utilization) &&
gpu_utilization == 0) {
if (m_gpu_idle_timer.at(domain_idx) > 0) {
m_gpu_idle_timer.at(domain_idx) = m_gpu_idle_timer.at(domain_idx) - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
m_gpu_idle_timer.at(domain_idx) = m_gpu_idle_timer.at(domain_idx) - 1;
m_gpu_idle_timer.at(domain_idx) -= 1;

m_gpu_idle_timer.at(domain_idx) = IDLE_SAMPLE_COUNT;
}

if (m_gpu_idle_timer.at(domain_idx) <= 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (m_gpu_idle_timer.at(domain_idx) <= 0) {
// If no activity has been observed for IDLE_SAMPLE_COUNT samples,
// we assume it is safe to reduce the frequency to a minimum value.
if (m_gpu_idle_timer.at(domain_idx) <= 0) {

Comment on lines 353 to 355
// If no activity has been observed for a number of samples
// IDLE_SAMPLE_COUNT we assume it is safe to reduce the frequency
// to a minimum value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// If no activity has been observed for a number of samples
// IDLE_SAMPLE_COUNT we assume it is safe to reduce the frequency
// to a minimum value.
// If activity is observed or is NAN, reset the IDLE_SAMPLE_COUNT tracking.

}

if (m_gpu_idle_timer.at(domain_idx) <= 0) {
f_request = m_freq_gpu_min;
Copy link
Contributor

@bgeltz bgeltz Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of the code in this method that has anything to do with calculating f_request could be refactored into it's own helper method. I started thinking about this because I'm seeing repeated code already:

                if (!std::isnan(gpu_utilization) &&
                    gpu_utilization == 0) {                 

I think this new code can be combined into the logic that starts on line 318 (new code), but further I think all of that can have an extract method refactor done on it to clean up adjust_platform() considerably, i.e. if the idle tracking time has expired and we're about to set the freq to min, we don't need to do any of the other frequency calculation above.

Comment on lines 26 to 31
// IDLE SAMPLE COUNT of 10 is based upon a study of the idle behavior of CORAL-2
// workloads of interest assuming the default 20ms sample rate (200ms idle).
// We could use 200ms as the default for the agent, but this does not provide a
// mechanism for user control of the idle period. Using a count provides partial
// user control in that the idleness period is defined by the requested agent
// control loop time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a #define instead of a const like M_CPU_ACTIVITY_CUTOFF and set in initializer list?

If we expect this is something the user would modify, it should be a policy parameter.

Comment on lines +387 to +390
// TODO: handle roll-over more gracefully than dropping a sample
if (m_gpu_energy.at(domain_idx).value > m_prev_gpu_energy.at(domain_idx)) {
m_gpu_on_energy.at(domain_idx) += m_gpu_energy.at(domain_idx).value - m_prev_gpu_energy.at(domain_idx);
}
Copy link
Contributor

@bgeltz bgeltz Sep 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty surprised that this is necessary here and not handled by the IOGroup.
AFAICT, the GPU_ENERGY signal and the CPU_ENERGY signal both have this same problem. The agents should not have to track this, and the IOGroups should be updated to deal with this.

The code in this agent could then be simplified, i.e. you don't need m_prev_gpu_energy at all if this was handled by the IOGroup.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this likely exists for CPU_ENERGY as well, but I have confirmed that the NVML and L0 IOGroups report the monotonic energy provided by the API (translated to SI units).
We could add a "GPU_ENERGY_DELTA" signal (final naming TBD) using the geopm DifferenceSignal class that provides the difference in the last sample and current sample and handles the rollover.

EXPECT_EQ(expected_header.at(i).first, report_header.at(i).first);
if (expected_header.at(i).first != "Agent Domain") {
EXPECT_EQ(std::stod(expected_header.at(i).second), std::stod(report_header.at(i).second));
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
};
}

EXPECT_EQ(expected_header.at(i).first, report_header.at(i).first);
if (expected_header.at(i).first != "Agent Domain") {
EXPECT_EQ(std::stod(expected_header.at(i).second), std::stod(report_header.at(i).second));
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
};
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also have a look at this, it may simplify this check:
https://stackoverflow.com/a/12340578

EXPECT_EQ(expected_header.at(i).first, report_header.at(i).first);
if (expected_header.at(i).first != "Agent Domain") {
EXPECT_EQ(std::stod(expected_header.at(i).second), std::stod(report_header.at(i).second));
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
};
}

…tainerEq

Signed-off-by: Lowren Lawson <lowren.h.lawson@intel.com>
Signed-off-by: Lowren Lawson <lowren.h.lawson@intel.com>
Signed-off-by: Lowren Lawson <lowren.h.lawson@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update GPU-CA to provide long idle handling
3 participants