提问人:greg spears 提问时间:11/6/2023 最后编辑:Peter Cordesgreg spears 更新时间:11/6/2023 访问量:164
这个基于 NOP 的 sleep()/delay() 函数使用了太多的 CPU 功率 (20%!) -- 如何解决?[复制]
This NOP-based sleep()/delay() function uses way too much CPU power (20%!) -- how to fix? [duplicate]
问:
我正在尝试构建一个跨平台的sleep()/delay()。下面的代码工作得很好,除了 - 与GCC或Microsoft sleep() - 不同 - 它不会将其CPU周期返回给操作系统。编译器原生 sleeps() 的好处是,您可以像我们的示例一样在循环中运行它们,并且 CPU 使用率接近于零。在此 delay() 代码中并非如此。它平均消耗高达 20%(!) 的 CPU。如果我将 #if defs 更改为调用 Sleep(),CPU 使用率将接近 0%。
“嗯,很明显,你的内联程序集显然是从最终的可执行文件中优化出来的,显然。”
这就是我的想法——这就是为什么我用现在注释掉的 ASM 代码进行测试,它增加了一个重要的循环。
我增加了循环数,直到它严重影响了延迟。也就是说,由于所有这些对 NOP 的调用,延迟时间比请求的 2 毫秒要长得多。因此,证据行为表明汇编代码在很大程度上是最终可执行文件的一部分。(它没有优化出来)。
我真的很惊讶 NOP 没有将 CPU 释放回操作系统!
那么,我们如何才能以一种 delay() 确实将其 CPU 周期返回给操作系统的方式进行编码,就像原生 sleep() 一样?
所需的平台是 WIN32 和 LINUX(稍后)。如果有人足够聪明,可以同时编写两者,那就太好了。但是,如果您只能回答一个问题,那么 WIN32 是现在/今天/这个问题的可接受答案,请并谢谢。
这是我尝试过的代码。我没想到会有如此强烈的 CPU 消耗。但是,不管NOP的大量使用--以及NOP的创造性实现--这就是我得到的。
#include <stdio.h>
#include <time.h>
void delay(int num)
{
clock_t start = clock();
while((clock() - start) < num )
{
#if 1
_asm{
//mov ECX,100000000
//lab5:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
//loop lab5
};
#else
Sleep(1);
#endif
}
}
int main()
{
unsigned iii=1000;
while(iii--)
{
printf("Count: %d \r",iii);
delay(2);
}
return 0;
}
答: 暂无答案
评论
nop
不是系统调用。CPU 必须获取并解码它才能看到接下来会发生什么。即使 x86 也不是系统调用,因此操作系统无法控制 CPU 以使其运行其他内容。pause
hlt
hlt
tpause
umonitor
umwait
sched_yield()
sleep
nanosleep
Sleep(0)
sched_yield