Skip to content

Commit

Permalink
i915-perf: build up tracking of GPU frequency values
Browse files Browse the repository at this point in the history
  • Loading branch information
llandwerlin-intel authored and mikesart committed Dec 30, 2020
1 parent 7640f24 commit 651ad4c
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 2 deletions.
19 changes: 18 additions & 1 deletion src/gpuvis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,8 +768,16 @@ int MainApp::load_etl_file( loading_info_t *loading_info, TraceEvents &trace_eve

int MainApp::load_i915_perf_file( loading_info_t *loading_info, TraceEvents &trace_events, EventCallback trace_cb )
{
return read_i915_perf_file( loading_info->filename.c_str(), trace_events.m_strpool,
int ret = read_i915_perf_file( loading_info->filename.c_str(), trace_events.m_strpool,
trace_events.m_trace_info, &trace_events.i915_perf_reader, trace_cb );

if ( ret == 0 )
{
trace_events.m_i915.freq_plot.init_empty( "i915-perf-freq" );
trace_events.m_i915.frequency_counter = get_i915_perf_frequency_counter( trace_events.i915_perf_reader );
}

return ret;
}

int SDLCALL MainApp::thread_func( void *data )
Expand Down Expand Up @@ -2119,6 +2127,11 @@ void TraceEvents::init_i915_event( trace_event_t &event )
}
}

void TraceEvents::add_i915_perf_frequency( const trace_event_t &event, int64_t ts, float value )
{
m_i915.freq_plot.add_item( event.id, ts, value );
}

void TraceEvents::init_i915_perf_event( trace_event_t &event )
{
if ( !event.has_duration() )
Expand All @@ -2138,6 +2151,10 @@ void TraceEvents::init_i915_perf_event( trace_event_t &event )
break;
}
}

// Load the GPU frequency data assocated with this event.
I915CounterCallback counter_cb = std::bind( &TraceEvents::add_i915_perf_frequency, this, _1, _2, _3 );
load_i915_perf_counter_values( i915_perf_reader, m_i915.frequency_counter, event, counter_cb );
}

m_i915.perf_locs.push_back( event.id );
Expand Down
13 changes: 13 additions & 0 deletions src/gpuvis.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

extern "C" {
struct intel_perf_data_reader;
struct intel_perf_logical_counter;
}

// Opts singleton
Expand Down Expand Up @@ -150,6 +151,10 @@ class GraphPlot
bool init( TraceEvents &trace_events, const std::string &name,
const std::string &filter_str, const std::string scanf_str );

void init_empty( const std::string &name );

void add_item( uint32_t eventid, int64_t ts, float value );

uint32_t find_ts_index( int64_t ts0 );

public:
Expand Down Expand Up @@ -449,6 +454,8 @@ class TraceEvents
}
uint32_t ts_to_ftrace_print_info_idx( const std::vector< uint32_t > &locs, int64_t ts );

void add_i915_perf_frequency( const trace_event_t &event, int64_t ts, float value );

public:
// Called once on background thread after all events loaded.
void init();
Expand Down Expand Up @@ -537,6 +544,12 @@ class TraceEvents
util_umap< uint32_t, uint32_t > perf_to_req_in;
// Maps a HW context ID to its color
std::map< uint32_t, ImU32 > perf_hw_context_colors;

// Frequency counter, filled right after parsing the i915-perf data.
struct intel_perf_logical_counter *frequency_counter = NULL;
// Plot generated after i915-perf data is parsed with the frequency
// counter values.
GraphPlot freq_plot;
} m_i915;

struct ftrace_pair_t
Expand Down
18 changes: 18 additions & 0 deletions src/gpuvis_plots.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,24 @@ bool GraphPlot::init( TraceEvents &trace_events, const std::string &name,
return !m_plotdata.empty();
}

void GraphPlot::init_empty( const std::string &name )
{
m_name = name;
m_filter_str.clear();
m_scanf_str.clear();

m_minval = FLT_MAX;
m_maxval = FLT_MIN;
m_plotdata.clear();
}

void GraphPlot::add_item( uint32_t eventid, int64_t ts, float value )
{
m_minval = std::min< float >( m_minval, value );
m_maxval = std::max< float >( m_maxval, value );
m_plotdata.push_back( { ts, eventid, value } );
}

uint32_t GraphPlot::find_ts_index( int64_t ts0 )
{
auto lambda = []( const GraphPlot::plotdata_t &lhs, int64_t ts )
Expand Down
66 changes: 66 additions & 0 deletions src/i915-perf/i915-perf-read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define _LARGEFILE64_SOURCE
#endif

#include <assert.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
Expand Down Expand Up @@ -111,3 +112,68 @@ int read_i915_perf_file( const char *file, StrPool &strpool, trace_info_t &trace

return 0;
}

#if USE_I915_PERF
static uint32_t record_timestamp( const struct drm_i915_perf_record_header *record )
{
const uint32_t *data = ( const uint32_t * )( record + 1 );
return data[ 1 ];
}
#endif

void load_i915_perf_counter_values( struct intel_perf_data_reader *reader,
struct intel_perf_logical_counter *counter,
const trace_event_t &event, I915CounterCallback &cb )
{
#if USE_I915_PERF
assert( event.i915_perf_timeline < reader->n_timelines );

const struct intel_perf_timeline_item *item = &reader->timelines[ event.i915_perf_timeline ];
const struct drm_i915_perf_record_header *first_record = reader->records[ item->record_start ];
for ( uint32_t j = item->record_start; j < item->record_end; j++ )
{
const struct drm_i915_perf_record_header *record = reader->records[j];
int64_t ts = item->cpu_ts_start +
( record_timestamp( record ) - record_timestamp( first_record ) ) *
( item->cpu_ts_end - item->cpu_ts_start ) / ( item->ts_end - item->ts_start );
struct intel_perf_accumulator acc;

intel_perf_accumulate_reports( &acc, reader->metric_set->perf_oa_format,
reader->records[j], reader->records[j + 1] );

float value;
if ( counter->storage == INTEL_PERF_LOGICAL_COUNTER_STORAGE_DOUBLE ||
counter->storage == INTEL_PERF_LOGICAL_COUNTER_STORAGE_FLOAT )
{
value = counter->read_float( reader->perf, reader->metric_set, acc.deltas );
}
else
{
value = counter->read_uint64( reader->perf, reader->metric_set, acc.deltas );
}

cb( event, ts, value / 1000000.0 ); // Report the frequency in MHz, not Hz
}
#endif
}

struct intel_perf_logical_counter *get_i915_perf_frequency_counter( struct intel_perf_data_reader *reader )
{
#if USE_I915_PERF
struct intel_perf_metric_set *metric_set = reader->metric_set;

for ( uint32_t i = 0; i < metric_set->n_counters; i++ )
{
struct intel_perf_logical_counter *counter = &metric_set->counters[ i ];

if ( strcmp( counter->symbol_name, "AvgGpuCoreFrequency" ) == 0 )
{
return counter;
}
}

return NULL;
#else
return NULL;
#endif
}
16 changes: 15 additions & 1 deletion src/i915-perf/i915-perf-read.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,22 @@
#ifndef I915_PERF_READ_H_
#define I915_PERF_READ_H_

struct intel_perf_data_reader;
#include <functional>

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

extern "C" {
struct intel_perf_data_reader;
struct intel_perf_logical_counter;
}

typedef std::function< void ( const trace_event_t &event, int64_t ts, float value ) > I915CounterCallback;

int read_i915_perf_file( const char *file, StrPool &strpool, trace_info_t &trace_info, struct intel_perf_data_reader **reader, EventCallback &cb );
struct intel_perf_logical_counter *get_i915_perf_frequency_counter( struct intel_perf_data_reader *reader );
void load_i915_perf_counter_values( struct intel_perf_data_reader *reader,
struct intel_perf_logical_counter *counter,
const trace_event_t &event, I915CounterCallback &cb );

#endif // I915_PERF_READ_H_

0 comments on commit 651ad4c

Please sign in to comment.