【发布时间】:2023-03-22 22:24:02
【问题描述】:
我做了一些 SO 搜索,发现 this 和 that 概述了计时方法。
我的问题是我需要确定执行以下循环所需的 CPU 时间(以毫秒为单位):
for (int i = 0, temp = 0; i < 10000; i++)
{
if (i % 2 == 0)
{
temp = (i / 2) + 1;
}
else
{
temp = 2 * i;
}
}
我研究了两种方法,clock() 和 stead_clock::now()。根据docs,我知道clock() 返回“滴答声”,因此我可以通过使用CLOCKS_PER_SEC 将差值除以秒来得到它。 docs 还提到 steady_clock 是为间隔计时而设计的,但您必须调用 duration_cast<milliseconds> 来更改其单位。
我为这两者计时所做的事情(因为在同一运行中同时执行这两个操作可能会导致一个需要更长的时间,因为另一个是先调用的)是自己运行它们:
clock_t t = clock();
for (int i = 0, temp = 0; i < 10000; i++)
{
if (i % 2 == 0)
{
temp = (i / 2) + 1;
}
else
{
temp = 2 * i;
}
}
t = clock() - t;
cout << (float(t)/CLOCKS_PER_SEC) * 1000 << "ms taken" << endl;
chrono::steady_clock::time_point p1 = chrono::steady_clock::now();
for (int i = 0, temp = 0; i < 10000; i++)
{
if (i % 2 == 0)
{
temp = (i / 2) + 1;
}
else
{
temp = 2 * i;
}
}
chrono::steady_clock::time_point p2 = chrono::steady_clock::now();
cout << chrono::duration_cast<milliseconds>(p2-p1).count() << "ms taken" << endl;
输出:
0ms taken
0ms taken
这两种方法都会影响结果吗?肯定发生了一些毫秒的分形?
那么对于确定执行循环所需的 CPU 时间,哪个是理想的(或者更确切地说,更合适)?乍一看,我会支持clock(),因为文档明确告诉我它用于确定 CPU 时间。
就上下文而言,我的CLOCKS_PER_SEC 的值为1000。
编辑/更新:
尝试了以下方法:
clock_t t = clock();
for (int j = 0; j < 1000000; j++) {
volatile int temp = 0;
for (int i = 0; i < 10000; i++)
{
if (i % 2 == 0)
{
temp = (i / 2) + 1;
}
else
{
temp = 2 * i;
}
}
}
t = clock() - t;
cout << (float(t) * 1000.0f / CLOCKS_PER_SEC / 1000000.0f) << "ms taken" << endl;
输出:0.019953 毫秒
clock_t start = clock();
volatile int temp = 0;
for (int i = 0; i < 10000; i++)
{
if (i % 2 == 0)
{
temp = (i / 2) + 1;
}
else
{
temp = 2 * i;
}
}
clock_t end = clock();
cout << fixed << setprecision(2) << 1000.0 * (end - start) / CLOCKS_PER_SEC << "ms taken" << endl;
输出:耗时 0.00 毫秒
chrono::high_resolution_clock::time_point p1 = chrono::high_resolution_clock::now();
volatile int temp = 0;
for (int i = 0; i < 10000; i++)
{
if (i % 2 == 0)
{
temp = (i / 2) + 1;
}
else
{
temp = 2 * i;
}
}
chrono::high_resolution_clock::time_point p2 = chrono::high_resolution_clock::now();
cout << (chrono::duration_cast<chrono::microseconds>(p2 - p1).count()) / 1000.0 << "ms taken" << endl;
输出:耗时 0.072 毫秒
chrono::steady_clock::time_point p1 = chrono::steady_clock::now();
volatile int temp = 0;
for (int i = 0; i < 10000; i++)
{
if (i % 2 == 0)
{
temp = (i / 2) + 1;
}
else
{
temp = 2 * i;
}
}
chrono::steady_clock::time_point p2 = chrono::steady_clock::now();
cout << (chrono::duration_cast<chrono::microseconds>(p2 - p1).count()) / 1000.0f << "ms taken" << endl;
输出:0.044ms
那么问题就变成了,哪个有效?第二种方法对我来说似乎无效,因为我认为循环完成的速度超过一毫秒。
我理解第一种方法(只是执行时间更长),但后两种方法产生的结果截然不同。
我注意到的一件事是,在编译程序后,我第一次运行它可能会得到 0.073 毫秒(high_resolution_clock)和 0.044 毫秒(steady_clock),但所有后续运行时间在 0.019 - 0.025ms 范围内。
【问题讨论】:
-
旁白:由于这段代码很愚蠢/毫无意义(它不断覆盖
temp的值,最终被丢弃),编译器可能会选择消除其全部或部分输出。无论如何,对于这么简单的一段代码来说,10.000 次迭代并不算多 - 尝试将循环计数提高几个数量级。 -
为什么你认为什么都不做需要时间?您的循环对程序的可观察行为没有影响
-
@500-InternalServerError 这样做了,他们确实产生了结果。我有同样的想法,但这些是我的限制。请参阅我对 Caleth 的回复。
-
@Caleth 执行此循环所需的时间稍后在对象程序中分配为 1 UT 的度量。所以我需要得到
1 UT = x ms,其中x是运行该循环的未知时间(以毫秒为单位)。 -
即使编译器没有优化所有内容,
0ms也可能是正确的结果。例如,2 * i与i + i相同,在 PC 上只需几分之一纳秒。
标签: c++