【问题标题】:Guarantee CPU response?保证CPU响应?
【发布时间】:2013-12-25 21:16:59
【问题描述】:

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

这是一个想法:

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) 阅读这些文章后:first、second 我意识到,有可能让我的应用程序每秒损失 30 微秒 = 0.00003 秒。这意味着,一天:0.00003*3600*24 = 2.592 秒/天。
c) 目前使用上面描述的最好的功能是每天损失 7 分钟。


我真正想做的事:

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

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

【问题讨论】:

  • 我不知道 C++ 库中对此有什么支持,但是使用 Posix 计时器函数,您指定绝对到期时间,而不是增量(您也可以指定重复间隔) .这将立即解决您的问题。
  • 按他们的时钟,这是 0.1 秒,而不是你的。你怎么这么确定他们在测量时间方面比你好得多?
  • 每天损失 3 秒不到 0.0035%。你确定你需要最后的 0.0035% 吗?
  • Oli 抓住了我所暗示的观点。假设由于网络抖动,您一天下载了 863999 个文件,下一天下载了 864001 个文件。突然被封号了?典型 IP 连接上的成帧时间有太多的抖动。为什么这里有疯狂的公差?此外,谁定义了日期的界限,以及当他们的时钟漂移时会发生什么,即使你的时钟是完美的?
  • @Blazer:我完全相信不到 0.1 秒。但你似乎误解了乔和我的观点。你是说跑的快过0.1秒就被封号了;我们是说,无论您的循环有多准确,您都会始终在连接的另一端看到 (A) 方差和 (B) 漂移。什么样的服务在执行如此精确的约束? (换句话说,我不相信这是真正的限制;))

标签: c# java c++ c assembly


【解决方案1】:

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

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 空闲。

顺便说一句,我建议忙等待而不是使用睡眠或任何阻塞操作系统的东西,因为这会干扰 CPU 缓存。也就是说,您的代码在唤醒后运行速度会明显变慢(2-5 倍),因为唤醒时间并不是您唯一需要担心的事情。

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

【讨论】:

  • 谢谢,我去看看。
【解决方案2】:

Java 内置了执行此操作的功能,带有ScheduledExecutorService 的选项之一是以固定rate 或固定delay 进行调度。

如果您使用固定速率选项,那么它将准确地为您提供您正在寻找的行为,这次运行所花费的时间将从延迟中减去,然后再次运行。

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

但是请注意,windows 是一个非实时操作系统,运行抢先式多任务。该服务将尝试在下次到来后尽快给您回电,但绝对不可能保证这样做。避免这种情况的唯一方法是切换到实时操作系统,但这真的是大材小用。

【讨论】:

  • 鉴于 Java 6 基本上是 EOL,我会从 Java 7 添加一个链接。
  • 好点,做到了(那个特定的类没有改变,但最好指向最新的文档)。
  • 这个答案往往会保留多年 +1 顺便说一句。
  • 谢谢,我也去看看。
【解决方案3】:

您无需控制 CPU 使用率,用户可以自行控制。通过在 Windows 中使用任务管理器。我相信您将不得不在程序代码中弄乱任务管理器。

【讨论】:

  • 非常感谢。我尝试在 Windows 系统上将优先级设置为实时。它有点帮助,但只有一个 Windows 7。与我想做的事情相去甚远。
猜你喜欢
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
相关资源
最近更新 更多