我正在寻找一个简单的操作/例程,如果不断重复,可能会“浪费”时间。
我正在研究gprof配置文件应用程序的方式,因此这种“浪费时间”需要在用户空间中浪费时间,并且不需要外部库。 IE,调用sleep(20)将“浪费”20秒的时间,但gprof不会记录这次,因为它发生在另一个库中。
对于可以重复浪费时间的简单任务的任何建议?
答案 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 compiled由clang
或gcc
或者可能是任何合理的编译器至少一些优化标志:
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"))
。