【发布时间】:2019-08-24 00:29:19
【问题描述】:
Windows 函数QueryThreadCycleTime() 给出了给定线程使用的“CPU 时钟周期”数。 Windows 手册大胆指出
不要尝试将 QueryThreadCycleTime 返回的 CPU 时钟周期转换为经过的时间。
我想对大多数 Intel 和 AMD x86_64 CPU 执行此操作。
它不需要非常准确,因为无论如何你不能期望像RDTSC 这样的循环计数器完美。
我只需要一些笨拙的方法来获取 CPU 的时间因子 seconds / QueryThreadCycleTime。
首先,我想QueryThreadCycleTime 在内部使用 RDTSC。
我想在某些 CPU 上使用恒定速率 TSC,因此更改实际时钟速率(例如,使用可变频率 CPU 电源管理)不会影响 time/TSC 因素。
在其他 CPU 上,该速率可能会发生变化,因此我必须定期查询该因素。
我为什么需要这个?
在有人引用XY Problem 之前,我应该指出我对替代解决方案并不真正感兴趣。 这是因为我有两个其他方法无法满足的分析硬性要求。
- 它应该只测量线程时间,所以
sleep(1)应该不返回 1 秒,而是持续 1 秒的繁忙循环应该。换句话说,分析器不应该说一个任务运行了 10 毫秒,而它的线程只活动了 1 毫秒。这就是我不能使用QueryPerformanceCounter()的原因。 - 需要一个优于1/64秒的精度,这是
GetThreadTimes()给出的精度。我正在分析的任务可能只运行几微秒。
最小的可重现示例
按照@Ted Lyngmo 的要求,目标是实现computeFactor()。
#include <stdio.h>
#include <windows.h>
double computeFactor();
int main() {
uint64_t start, end;
QueryThreadCycleTime(GetCurrentThread(), &start);
// insert task here, such as an actual workload or sleep(1)
QueryThreadCycleTime(GetCurrentThread(), &end);
printf("%lf\n", (end - start) * computeFactor());
return 0;
}
【问题讨论】:
-
“对替代解决方案并不真正感兴趣”到什么解决方案?您当前的非工作解决方案(在代码中)是什么?
-
我之所以要求您提供当前无效的解决方案,是为了让您发布它以触发人们给出答案。我个人认为它是相关的,没有它就不会尝试回答。
-
很公平。您可以使用 VCV Rack 1.1.4 (vcvrack.com/Rack.html) 的 Windows 版本并通过启用“引擎 > CPU 计量器”在生产中试用结果。
-
当 API 被记录为不适合特定用途,并且该 API 的发布者对该主题非常了解(MS 不是 joeblow@mymomsbasement.com)时,您应该接受作为准确的信息。期望他们知道的比你少,你无论如何都能让它工作,这有点不合理,期望我们为你做这项工作更不合理。你的要求是行不通的,与其浪费时间尝试去做,你应该改变你的立场,寻求替代解决方案。