保证CPU响应?

时间:2013-12-25 21:16:59

标签: c# java c++ c assembly

注意:我更喜欢C ++(下面的代码是C ++)但如果有人设法在任何通用语言中执行以下操作,我很乐意。

这是一个想法:

a)计时器启动 b)功能执行并且始终小于0.1秒 c)程序休眠直到与开始的时间差完全 0.1秒 d)永远重复。

如果睡眠时间略高于0.1秒,比如0.105秒,我每秒损失0.005秒。这个不准确的费用在我的申请中,因为我在一天内输了:0.005 * 3600 * 24 = 432秒。

我的申请是实时申请;我失去的时间并不重要。


执行:

a)一步很简单,只需设置一个变量x = std::chrono::high_resolution_clock::now(); b)运行功能
c)中

while((std::chrono::high_resolution_clock::now()-x).count() < 1000000)
        std::this_thread::sleep_for(std::chrono::nanoseconds(1));

d)循环


要点:

a)我明白,无论如何,我每秒至少会损失1纳秒 b)阅读完这些文章之后:firstsecond我意识到,我的应用程序可能每秒丢失30微秒= 0.00003秒。这意味着,在一天中:0.00003 * 3600 * 24 =每天2.592秒 c)目前使用上述功能,我管理的最佳功能是每天丢失7分钟。


我真正想做的事情:

我可以访问具有一个限制的服务器:每0.1秒只允许一个请求。如果它需要更少,他们将禁止我。如果我的请求需要更长时间,我下载的数据更少。我的应用程序每0.1秒下载一个文件。如果由于延迟我每天损失432秒,这意味着我可以下载4320个文件。

问:如何在CentOS上实施CPU屏蔽,或其他任何操作系统?

3 个答案:

答案 0 :(得分:7)

如果你不想浪费一天的时间,你就不会像这样实现你的代码。你会做类似

的事情
for(long next = System.currentTimeMillis() + 100;; start += 100) {
    // do something
    while(true){
        long delay = next - System.currentTimeMillis();
        if (delay <= 0)
            break;
        Thread.sleep(delay);
    }
}

通过这种方式,您可以在裸机上获得长达5毫秒的抖动,在虚拟机管理程序上获得50毫秒的抖动,但这将在下一次迭代或之后的迭代中消失。

即。此代码中没有累积漂移。 (注意:高分辨率定时器漂移但这取决于您的硬件)

我怀疑你实际上是在尝试解决另一个你在这里没有解释过的问题。

  

如何在CentOS上实现CPU屏蔽,或其他任何操作系统?

我为Java做的是

  • 对要隔离的每个核心使用isocpus = 5,6,11,12或每个CPU。我建议隔离整个核心。这允许您有选择地使用超线程。
  • 配置IRQ平衡以避免使用这些CPU,除非您打算在此CPU的线程中使用它们。
  • 使用sched_setaffinity将选定的线程绑定到各个CPU。要分配整个核心,请将核心的一个CPU保持空闲状态。

BTW我建议忙于等待而不是使用睡眠或操作系统中阻塞的任何东西,因为这会干扰CPU缓存。即醒来后你的代码运行速度会明显变慢(2-5x),因为唤醒时间不是你唯一需要担心的事情。

BTW2我没有在Windows上找到一种可靠的CPU屏蔽方式,除了设置尽可能高的优先级,注意:除非以管理员身份运行,否则无法提高优先级。在Linux上,提高优先级并不如从正常调度中移除CPU那样有效。

答案 1 :(得分:3)

Java具有内置功能,ScheduledExecutorService的其中一个选项是以固定的速率或固定的延迟安排。< / p>

如果您使用固定费率选项,那么它将为您提供您正在寻找的行为,此时间运行所花费的时间将从再次运行之前的延迟中减去。

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

但请注意,Windows是一个非抢占式多任务运行的非实时操作系统。该服务将在下一次出现后尽快给您回电,但绝对不可能保证这样做。避免这种情况的唯一方法是切换到实时操作系统,但这实在是太过分了。

答案 2 :(得分:0)

您无需控制自己可以控制的用户的CPU使用率。在Windows中使用任务管理器。我相信你必须在程序代码中弄乱任务管理器。