简单的操作浪费时间?

时间:2011-08-18 09:59:49

标签: c++ profiling benchmarking gprof

我正在寻找一个简单的操作/例程,如果不断重复,可能会“浪费”时间。

我正在研究gprof配置文件应用程序的方式,因此这种“浪费时间”需要在用户空间中浪费时间,并且不需要外部库。 IE,调用sleep(20)将“浪费”20秒的时间,但gprof不会记录这次,因为它发生在另一个库中。

对于可以重复浪费时间的简单任务的任何建议?

4 个答案:

答案 0 :(得分:6)

在不产生CPU的情况下“浪费”时间的最简单方法是一个紧凑的循环。

如果您不需要限制浪费的持续时间(例如,您在完成后通过简单地终止流程来控制它),那么请转到C风格 *

for (;;) {}

(但是,请注意,该标准允许实现假定程序最终将终止,因此从技术上讲,此循环 - 至少在C ++ 0x中 - 具有未定义的行为并且可以优化出来! * *

否则,您可以手动计时:

time_t s = time(0);
while (time(0) - s < 20) {}

或者,不是重复发出time系统调用(这将导致在内核中花费一些时间),如果在GNU兼容系统上,您可以使用{{ 1}} "alarms"结束循环:

signal.h

"Handler Returns"的文档页面上甚至有一个非常类似的例子。

(当然,这些方法都会让你在一段时间内将100%的CPU送到你手中,让蓬松的独角兽从你的耳朵里掉出来。)


为了清楚起见,

* alarm(20); while (true) {} 而不是故意使用尾随{}。最终,没有理由在这样的上下文中编写分号;当你在“真实”的代码中使用它时,这是一个可怕的习惯,并成为一个维护陷阱。

**请参阅;[n3290: 1.10/2]

答案 1 :(得分:6)

Tomalak解决方案的另一个变体是set up an alarm,因此在忙碌等待循环中,您不需要继续发出系统调用,而只需检查信号是否已发送。

答案 2 :(得分:0)

一个简单的循环可以。 如果你正在研究gprof是如何工作的,我假设你已经read the paper, slowly and carefully了。 我还假设你熟悉these issues

答案 3 :(得分:0)

这里是一个繁忙的循环,它在现代硬件上每次迭代运行一个周期,至少as compiledclanggcc或者可能是任何合理的编译器至少一些优化标志:

void busy_loop(uint64_t iters) {
    volatile int sink;
    do {
        sink = 0;
    } while (--iters > 0);
    (void)sink;
}

这个想法只是每次迭代都存储到volatile sink。这可以防止循环被优化掉,并使每次迭代具有可预测的工作量(至少一个存储)。现代硬件每个周期可以做一个存储,并且循环开销通常可以在同一个周期内并行完成,因此通常每次迭代实现一个周期。所以你可以通过除以你的CPU速度(以GHz为单位)得到iters给定的busy_loop所需的挂钟时间(以纳秒为单位)。例如,iters == 6,000,000,000时,3 GHz CPU将花费大约2秒(20亿纳秒)到 =iif((Fields!Type.Value="Discovery Email Sent") and (datediff("d",Fields!CreatedDate.Value,Fields!ArrivalDate.Value)<90),"red","white") or (iif((Fields!Type.Value="Menu Proposal Sent") and (datediff("d",Fields!CreatedBy.Value,Fields!ArrivalDate.Value)<60),"red","white"))