Skip to content

Commit 070598e

Browse files
[SYCL][L0] Do not use piGetDeviceAndHostTimer for only host time query (#8996)
Use steady_clock::now() to retrieve host time as piGetDeviceAndHostTimer has much large overhead (it retrieves both device and host times, synchronized). --------- Signed-off-by: Sergey V Maslov <[email protected]>
1 parent 0db1f8d commit 070598e

File tree

2 files changed

+46
-46
lines changed

2 files changed

+46
-46
lines changed

sycl/plugins/level_zero/pi_level_zero.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5012,9 +5012,9 @@ pi_result piEventGetProfilingInfo(pi_event Event, pi_profiling_info ParamName,
50125012
case PI_PROFILING_INFO_COMMAND_QUEUED:
50135013
case PI_PROFILING_INFO_COMMAND_SUBMIT:
50145014
// Note: No users for this case
5015-
// TODO: Implement commmand submission time when needed,
5016-
// by recording device timestamp (using zeDeviceGetGlobalTimestamps)
5017-
// before submitting command to device
5015+
// The "command_submit" time is implemented by recording submission
5016+
// timestamp with a call to piGetDeviceAndHostTimer before command enqueue.
5017+
//
50185018
return ReturnValue(uint64_t{0});
50195019
default:
50205020
urPrint("piEventGetProfilingInfo: not supported ParamName\n");
@@ -8677,7 +8677,6 @@ pi_result piGetDeviceAndHostTimer(pi_device Device, uint64_t *DeviceTime,
86778677
&DeviceClockCount));
86788678

86798679
if (DeviceTime != nullptr) {
8680-
86818680
*DeviceTime = (DeviceClockCount & TimestampMaxCount) * ZeTimerResolution;
86828681
}
86838682
return PI_SUCCESS;

sycl/source/detail/device_impl.cpp

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -441,53 +441,54 @@ std::string device_impl::getDeviceName() const {
441441
return MDeviceName;
442442
}
443443

444-
/* On first call this function queries for device timestamp
445-
along with host synchronized timestamp
446-
and stores it in memeber varaible deviceTimePair.
447-
Subsequent calls to this function would just retrieve the host timestamp ,
448-
compute difference against the host timestamp in deviceTimePair
449-
and calculate the device timestamp based on the difference.
450-
deviceTimePair is refreshed with new device and host timestamp after a
451-
certain interval (determined by timeTillRefresh) to account for clock drift
452-
between host and device.
453-
*/
454-
444+
// On first call this function queries for device timestamp
445+
// along with host synchronized timestamp and stores it in memeber varaible
446+
// MDeviceHostBaseTime. Subsequent calls to this function would just retrieve
447+
// the host timestamp, compute difference against the host timestamp in
448+
// MDeviceHostBaseTime and calculate the device timestamp based on the
449+
// difference.
450+
//
451+
// The MDeviceHostBaseTime is refreshed with new device and host timestamp
452+
// after a certain interval (determined by TimeTillRefresh) to account for
453+
// clock drift between host and device.
454+
//
455455
uint64_t device_impl::getCurrentDeviceTime() {
456-
// To account for potential clock drift between host clock and device clock.
457-
// The value set is arbitrary: 200 seconds
458-
constexpr uint64_t timeTillRefresh = 200e9;
459-
460-
uint64_t hostTime;
456+
using namespace std::chrono;
457+
uint64_t HostTime =
458+
duration_cast<nanoseconds>(steady_clock::now().time_since_epoch())
459+
.count();
461460
if (MIsHostDevice) {
462-
using namespace std::chrono;
463-
return duration_cast<nanoseconds>(steady_clock::now().time_since_epoch())
464-
.count();
461+
return HostTime;
465462
}
466-
auto plugin = getPlugin();
467-
RT::PiResult result =
468-
plugin.call_nocheck<detail::PiApiKind::piGetDeviceAndHostTimer>(
469-
MDevice, nullptr, &hostTime);
470-
plugin.checkPiResult(result == PI_ERROR_INVALID_OPERATION ? PI_SUCCESS
471-
: result);
472-
473-
if (result == PI_ERROR_INVALID_OPERATION) {
474-
char *p = nullptr;
475-
plugin.call_nocheck<detail::PiApiKind::piPluginGetLastError>(&p);
476-
std::string errorMsg(p ? p : "");
477-
throw sycl::feature_not_supported(
478-
"Device and/or backend does not support querying timestamp: " +
479-
errorMsg,
480-
result);
481-
}
482-
uint64_t diff = hostTime - MDeviceHostBaseTime.second;
483463

484-
if (diff > timeTillRefresh || diff <= 0) {
485-
plugin.call<detail::PiApiKind::piGetDeviceAndHostTimer>(
486-
MDevice, &MDeviceHostBaseTime.first, &MDeviceHostBaseTime.second);
487-
diff = 0;
464+
// To account for potential clock drift between host clock and device clock.
465+
// The value set is arbitrary: 200 seconds
466+
constexpr uint64_t TimeTillRefresh = 200e9;
467+
uint64_t Diff = HostTime - MDeviceHostBaseTime.second;
468+
469+
if (Diff > TimeTillRefresh || Diff <= 0) {
470+
auto Plugin = getPlugin();
471+
auto Result =
472+
Plugin.call_nocheck<detail::PiApiKind::piGetDeviceAndHostTimer>(
473+
MDevice, &MDeviceHostBaseTime.first, &MDeviceHostBaseTime.second);
474+
475+
if (Result == PI_ERROR_INVALID_OPERATION) {
476+
char *p = nullptr;
477+
Plugin.call_nocheck<detail::PiApiKind::piPluginGetLastError>(&p);
478+
std::string errorMsg(p ? p : "");
479+
throw sycl::feature_not_supported(
480+
"Device and/or backend does not support querying timestamp: " +
481+
errorMsg,
482+
Result);
483+
} else {
484+
Plugin.checkPiResult(Result);
485+
}
486+
// Until next sync we will compute device time based on the host time
487+
// returned in HostTime, so make this our base host time.
488+
MDeviceHostBaseTime.second = HostTime;
489+
Diff = 0;
488490
}
489-
490-
return MDeviceHostBaseTime.first + diff;
491+
return MDeviceHostBaseTime.first + Diff;
491492
}
492493

493494
} // namespace detail

0 commit comments

Comments
 (0)