减缓线程速度的最佳方法?使用Sleep()可以吗? 我写了一个C++库,它做了一些非常重的CPU工作(所有的数学和计算),如果它自己的设备,将很容易地消耗所有可用CPU资源的100%(它也与机器上可用的逻辑内核的数量多线程)。

减缓线程速度的最佳方法?使用Sleep()可以吗? 我写了一个C++库,它做了一些非常重的CPU工作(所有的数学和计算),如果它自己的设备,将很容易地消耗所有可用CPU资源的100%(它也与机器上可用的逻辑内核的数量多线程)。,c++,performance,multithreading,sleep,cpu-usage,C++,Performance,Multithreading,Sleep,Cpu Usage,因此,我在使用库的软件应该调用的主计算循环中有一个回调: while(true) { //do math here callback(percent_complete); } 在回调中,客户端调用Sleep(x)来减慢线程的速度 最初,客户端代码是一个固定的Sleep(100)调用,但这导致了不可靠的性能,因为有些机器完成数学运算的速度比其他机器快,但所有机器上的睡眠都是相同的。因此,现在客户端检查系统时间,如果超过1秒(即==多次迭代),它将休眠半秒 这是降低线程速度的一种可

因此,我在使用库的软件应该调用的主计算循环中有一个回调:

while(true)
{
    //do math here
    callback(percent_complete);
}
在回调中,客户端调用Sleep(x)来减慢线程的速度

最初,客户端代码是一个固定的Sleep(100)调用,但这导致了不可靠的性能,因为有些机器完成数学运算的速度比其他机器快,但所有机器上的睡眠都是相同的。因此,现在客户端检查系统时间,如果超过1秒(即==多次迭代),它将休眠半秒

这是降低线程速度的一种可接受的方法吗?我应该使用信号量/互斥量而不是Sleep()来最大限度地提高性能吗?在处理过程中,每1秒睡眠x毫秒是否正常,还是有什么我没有注意到的错误

我问这个问题的原因是,尽管taskman显示进程占用了约10%的CPU,但机器仍然陷入了严重的困境。我已经研究了硬盘和内存争用,但没有结果,所以现在我想知道是否是我减慢线程速度的方式导致了这个问题


谢谢

为什么不为计算线程使用较低的优先级?这将确保调度其他线程,同时允许您的计算线程在不需要运行其他线程的情况下尽可能快地运行

睡眠对于限制应用程序来说应该是很好的,从你的评论来看,这就是你想要的。也许你只需要更精确地知道你的睡眠时间

我使用的唯一一个软件就是。我不知道它使用的是什么机制,但它是开源和多平台的,所以请自便

它有一个配置选项(“将CPU使用限制为X%”。我希望实现这一点的方法是使用依赖于平台的API,如
clock()
GetSystemTimes()
,并将处理器时间与占用的挂钟时间进行比较。做一些真正的工作,检查你是否已经过或低于标准,如果你超过标准睡眠一段时间,回到下面。

BOINC客户端可以很好地处理优先级,即使在100%最大CPU的情况下,也不会对其他应用程序造成任何性能问题。我之所以使用节流阀,是因为在其他情况下,客户机会一直将CPU耗尽,并提高风扇速度和噪音。所以我在风扇保持安静的水平运行它。如果冷却效果更好,我可能就不需要它了:-)

看看。它根据需要发送
SIGSTOP
SIGCONT
,以使进程低于给定的CPU使用率百分比

即便如此,WTF仍在“关于你的软件扼杀PC性能的疯狂抱怨和古怪评论”。我更可能抱怨你的软件速度慢,没有充分利用我的硬件,但我不是你的客户


编辑:在Windows上,
SuspendThread()
ResumeThread()
可能会产生类似的行为。

另一种不太复杂的方法是计时一次迭代,让线程休眠(x*t)下一次迭代前的毫秒,其中t是一次迭代的毫秒时间,x是选择的睡眠时间分数(介于0和1之间)

100%的CPU有什么问题?这是你应该努力争取的,而不是试图避免的。这些数学计算很重要,不是吗?除非您试图避免占用一些其他资源,而这些资源不是由操作系统(互斥体、磁盘等)显式管理并由主线程使用,否则通常尝试降低线程速度是一个坏主意。在多核系统上(几乎所有的系统都将是这样),情况如何?你会毫无理由地减慢线程的速度

操作系统有一个线程量的概念。它将负责确保系统上没有重要的线程被饿死。而且,正如我所提到的,在多核系统上,在一个CPU上增加一个线程不会损害其他内核上其他线程的性能

我还在另一条评论中看到,这个线程也在进行大量的磁盘I/O操作——这些操作已经会导致线程在等待结果时出现问题,因此休眠将不会起任何作用


一般来说,如果您调用Sleep(x),那么您的设计有问题/懒惰,如果x==0,您将打开自己的活动锁(调用Sleep(0)的线程实际上可以立即重新调度,使其成为noop)。

实际上,这在Windows上不是很可靠。我已经将这个库移植到了OSX上,在那里它的工作就像一个低优先级的梦,但是在Windows上它仍然会引起问题。还有一件事:出于营销/技术支持的目的,我们发现让taskmanager中的软件占用超过20%的CPU是一个坏主意,否则你会收到一些疯狂的抱怨和奇怪的评论,说你的软件扼杀了PC的性能。人们看到50%的CPU使用率和恐慌!我说不出你的港口为什么会这样。根据我的经验,调度在Windows上运行得很好。在任何情况下,考虑到这个问题,我认为最好使用优先级并将调度留给OS.Computer Guru来解决,线程优先级在Windows上工作得相当可靠。但是,如果您正在进行大量的I/O(不管是直接的还是由内存分页引起的),您可能还需要降低I/O优先级。请参阅SetThreadPriority和THREAD_MODE_BACKGROUND_BEGIN。谢谢,avakar。我没有想到这一点——确实涉及到相当多的文件读写操作(尽管它现在被缓冲在4MB的块中,我不确定当我第一次尝试降低线程优先级时是否如此),以及大量的内存分页(这本身就是另一个问题)。我给你一个嘘