adding rocprofiler_get_time API
Change-Id: I9202b3e97f8f9ca7485f87ea22746a9c4d8091c3
Этот коммит содержится в:
@@ -376,13 +376,25 @@ hsa_status_t rocprofiler_query_info(
|
||||
hsa_status_t (*callback)(const rocprofiler_info_data_t info, void *data), // callback
|
||||
void *data); // [in/out] data passed to callback
|
||||
|
||||
// Creates a profiled queue. All dispatches on this queue will be profiled
|
||||
// Create a profiled queue. All dispatches on this queue will be profiled
|
||||
hsa_status_t rocprofiler_queue_create_profiled(
|
||||
hsa_agent_t agent_handle,uint32_t size, hsa_queue_type32_t type,
|
||||
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data),
|
||||
void* data, uint32_t private_segment_size, uint32_t group_segment_size,
|
||||
hsa_queue_t** queue);
|
||||
|
||||
// Convert profiler time
|
||||
typedef enum {
|
||||
ROCPROFILER_TIME_ID_CLOCK_REALTIME = 0,
|
||||
ROCPROFILER_TIME_ID_CLOCK_MONOTONIC = 1,
|
||||
} rocprofiler_time_id_t;
|
||||
|
||||
// Return time for a given time ID and profiling timetsamp value
|
||||
hsa_status_t rocprofiler_get_time(
|
||||
rocprofiler_time_id_t time_id, // identifier of the particular time to convert the timesatmp
|
||||
uint64_t value, // profiling timestamp value
|
||||
uint64_t* time); // returned time
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Profiling pool
|
||||
//
|
||||
|
||||
@@ -843,4 +843,13 @@ PUBLIC_API hsa_status_t rocprofiler_queue_create_profiled(
|
||||
return rocprofiler::InterceptQueue::QueueCreateTracked(agent, size, type, callback, data, private_segment_size, group_segment_size, queue);
|
||||
}
|
||||
|
||||
// Return time for a given time ID and profiling timetsamp value
|
||||
hsa_status_t rocprofiler_get_time(
|
||||
rocprofiler_time_id_t time_id,
|
||||
uint64_t value,
|
||||
uint64_t* time)
|
||||
{
|
||||
return rocprofiler::util::HsaRsrcFactory::Instance().GetTime(time_id, value, time);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -150,6 +150,19 @@ HsaRsrcFactory::HsaRsrcFactory(bool initialize_hsa) : initialize_hsa_(initialize
|
||||
CHECK_STATUS("HSA timer allocation failed",
|
||||
(timer_ == NULL) ? HSA_STATUS_ERROR : HSA_STATUS_SUCCESS);
|
||||
|
||||
// Time correlation
|
||||
const uint32_t corr_iters = 1000;
|
||||
CorrelateTime(HsaTimer::TIME_ID_CLOCK_REALTIME, corr_iters);
|
||||
CorrelateTime(HsaTimer::TIME_ID_CLOCK_MONOTONIC, corr_iters);
|
||||
#if 0
|
||||
printf("ROCProfiler time CLOCK_REALTIME: shift(0x%016lx) error(0x%lx)\n",
|
||||
time_shift_[HsaTimer::TIME_ID_CLOCK_REALTIME],
|
||||
time_error_[HsaTimer::TIME_ID_CLOCK_REALTIME]);
|
||||
printf("ROCProfiler time CLOCK_MONOTONIC: shift(0x%016lx) error(0x%lx)\n",
|
||||
time_shift_[HsaTimer::TIME_ID_CLOCK_MONOTONIC],
|
||||
time_error_[HsaTimer::TIME_ID_CLOCK_MONOTONIC]);
|
||||
#endif
|
||||
|
||||
// System timeout
|
||||
timeout_ = (timeout_ns_ == HsaTimer::TIMESTAMP_MAX) ? timeout_ns_ : timer_->ns_to_sysclock(timeout_ns_);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
@@ -177,6 +178,12 @@ class HsaTimer {
|
||||
static const timestamp_t TIMESTAMP_MAX = UINT64_MAX;
|
||||
typedef long double freq_t;
|
||||
|
||||
enum time_id_t {
|
||||
TIME_ID_CLOCK_REALTIME = 0,
|
||||
TIME_ID_CLOCK_MONOTONIC = 1,
|
||||
TIME_ID_NUMBER
|
||||
};
|
||||
|
||||
HsaTimer(const hsa_pfn_t* hsa_api) : hsa_api_(hsa_api) {
|
||||
timestamp_t sysclock_hz = 0;
|
||||
hsa_status_t status = hsa_api_->hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &sysclock_hz);
|
||||
@@ -192,6 +199,11 @@ class HsaTimer {
|
||||
return timestamp_t((freq_t)time / sysclock_factor_);
|
||||
}
|
||||
|
||||
// Method for timespec/ns conversion
|
||||
timestamp_t timespec_to_ns(const timespec& time) const {
|
||||
return ((timestamp_t)time.tv_sec * 1000000000) + time.tv_nsec;
|
||||
}
|
||||
|
||||
// Return timestamp in 'ns'
|
||||
timestamp_t timestamp_ns() const {
|
||||
timestamp_t sysclock;
|
||||
@@ -200,6 +212,54 @@ class HsaTimer {
|
||||
return sysclock_to_ns(sysclock);
|
||||
}
|
||||
|
||||
// Return time in 'ns'
|
||||
timestamp_t clocktime_ns(clockid_t clock_id) const {
|
||||
timespec time;
|
||||
clock_gettime(clock_id, &time);
|
||||
return timespec_to_ns(time);
|
||||
}
|
||||
|
||||
// Return pair of correlated values of profiling timestamp and time with
|
||||
// correlation error for a given time ID and number of iterations
|
||||
void correlated_pair_ns(time_id_t time_id, uint32_t iters,
|
||||
timestamp_t* timestamp_v, timestamp_t* time_v, timestamp_t* error_v) {
|
||||
clockid_t clock_id = 0;
|
||||
switch (clock_id) {
|
||||
case TIME_ID_CLOCK_REALTIME:
|
||||
clock_id = CLOCK_REALTIME;
|
||||
break;
|
||||
case TIME_ID_CLOCK_MONOTONIC:
|
||||
clock_id = CLOCK_MONOTONIC;
|
||||
break;
|
||||
default:
|
||||
CHECK_STATUS("internal error: invalid time_id", HSA_STATUS_ERROR);
|
||||
}
|
||||
|
||||
std::vector<timestamp_t> ts_vec(iters);
|
||||
std::vector<timespec> tm_vec(iters);
|
||||
const uint32_t steps = iters - 1;
|
||||
|
||||
for (uint32_t i = 0; i < iters; ++i) {
|
||||
hsa_api_->hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP, &ts_vec[i]);
|
||||
clock_gettime(clock_id, &tm_vec[i]);
|
||||
}
|
||||
|
||||
const timestamp_t ts_base = sysclock_to_ns(ts_vec.front());
|
||||
const timestamp_t tm_base = timespec_to_ns(tm_vec.front());
|
||||
const timestamp_t error = (ts_vec.back() - ts_vec.front()) / (2 * steps);
|
||||
|
||||
timestamp_t ts_accum = 0;
|
||||
timestamp_t tm_accum = 0;
|
||||
for (uint32_t i = 0; i < iters; ++i) {
|
||||
ts_accum += (ts_vec[i] - ts_base);
|
||||
tm_accum += (timespec_to_ns(tm_vec[i]) - tm_base);
|
||||
}
|
||||
|
||||
*timestamp_v = (ts_accum / iters) + ts_base + error;
|
||||
*time_v = (tm_accum / iters) + tm_base;
|
||||
*error_v = error;
|
||||
}
|
||||
|
||||
private:
|
||||
// Timestamp frequency factor
|
||||
freq_t sysclock_factor_;
|
||||
@@ -359,6 +419,21 @@ class HsaRsrcFactory {
|
||||
if (instance_ != NULL) Instance().timeout_ = Instance().timer_->ns_to_sysclock(time);
|
||||
}
|
||||
|
||||
void CorrelateTime(HsaTimer::time_id_t time_id, uint32_t iters) {
|
||||
timestamp_t timestamp_v = 0;
|
||||
timestamp_t time_v = 0;
|
||||
timestamp_t error_v = 0;
|
||||
timer_->correlated_pair_ns(time_id, iters, ×tamp_v, &time_v, &error_v);
|
||||
time_shift_[time_id] = time_v - timestamp_v;
|
||||
time_error_[time_id] = error_v;
|
||||
}
|
||||
|
||||
hsa_status_t GetTime(uint32_t time_id, uint64_t value, uint64_t* time) {
|
||||
if (time_id >= HsaTimer::TIME_ID_NUMBER) return HSA_STATUS_ERROR;
|
||||
*time = value + time_shift_[time_id];
|
||||
return HSA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
private:
|
||||
// System agents iterating callback
|
||||
static hsa_status_t GetHsaAgentsCallback(hsa_agent_t agent, void* data);
|
||||
@@ -423,6 +498,10 @@ class HsaRsrcFactory {
|
||||
// HSA timer
|
||||
HsaTimer* timer_;
|
||||
|
||||
// Time shift array to support time conversion
|
||||
timestamp_t time_shift_[HsaTimer::TIME_ID_NUMBER];
|
||||
timestamp_t time_error_[HsaTimer::TIME_ID_NUMBER];
|
||||
|
||||
// CPU/kern-arg memory pools
|
||||
hsa_amd_memory_pool_t *cpu_pool_;
|
||||
hsa_amd_memory_pool_t *kern_arg_pool_;
|
||||
|
||||
Ссылка в новой задаче
Block a user