【问题标题】:How do you program time? [closed]你如何编程时间? [关闭]
【发布时间】:2013-09-18 12:56:13
【问题描述】:

这听起来可能是一个奇怪的问题,但是如何在不使用编程语言的 API 的情况下对时间进行编程呢?时间是一个如此抽象的概念,不使用预定义的时间函数怎么写程序。

我在想它必须通过处理器计算的计数来计算,但如果每台计算机的速度性能不同,你将如何编写代码来迭代时间。

假设编写程序的语言无关紧要,你会怎么做?

编辑:我还应该说,不使用系统时间,或系统中任何预先生成的时间版本

【问题讨论】:

  • 时间是一个抽象的概念,如果你在宇宙和太空旅行的哲学辩论中。在编程中它被计算为秒和微秒。
  • 在 C++ 中,有std::chrono::high_resolution_clockstd::chrono::system_clockstd::chrono::steady_clock 等用于测量时间。该实现由标准库提供,因此用户无需担心 TICK_PER_CYCLE 等等。
  • 但是你能不使用那些 C++ 方法来做到这一点就是我要问的......不使用操作系统的系统时间。
  • 所以你想测量时间,但不想使用任何与内置系统时钟相关的东西? ...你高吗?
  • 你确定吗?因为计算机具有任何时间概念的唯一方法是基于硬件时钟,这与手表中的时钟基本相同。如果没有那个硬件时钟和轮询它的系统调用,您的计算机甚至无法告诉您它的时钟速度是多少。它所能告诉你的只是“自上次任意轮询以来,我已经完成了 X 个周期”。

标签: java php c++


【解决方案1】:

在 Java 中,您会注意到获取时间的最简单方法是

System.currentTimeMillis();

实现为

public static native long currentTimeMillis();

这是一个用本机代码实现的native 方法,很可能是c。您计算机的 CPU 有一个 internal clock 可以自行调整。本机调用是操作系统调用硬件以检索该值,可能在某处进行一些软件转换。

【讨论】:

  • 但是不使用系统时钟,可以生成时间吗?
  • @Arian 你可以取一个随机值,但是你不能计算经过的时间,不。
【解决方案2】:

有可能,但是我怀疑这需要相当长的时间。

您可以使用您的计算机被宇宙射线击中的概率。

参考:Cosmic Rays: what is the probability they will affect a program?

您需要创建一个程序来处理计算机内存中的大量数据,从而使其容易受到宇宙射线的入侵。此类数据将在某个时间点损坏。 该程序应该能够检查数据的完整性并标记其数据部分损坏的时刻。发生这种情况时,程序还应该能够生成另一个参考框架,例如给定函数在两条宇宙射线命中之间运行多少次。

然后,这些间隔应记录在数据库中,并在发生数十亿/万亿/亿次后取平均值,从而减少发生的宇宙射线撞击的预计随机性。

从那时起,计算机将能够通过宇宙射线平均命中系数来判断时间。

当然,这是一个过于简单的解决方案。我很确定硬件在这段时间内会出现故障,宇宙射线可能会击中内存的可运行代码区域而不是原始数据,宇宙射线可能会由于我们的太阳系在银河系中的连续运动而改变发生率等。

不过,确实有可能...

【讨论】:

  • 理论上我喜欢这个解决方案,并且使用适当的空间额定硬件(具有容错能力的 CPU 和即使在随机损坏时也具有确定性的操作系统),它可以在实践中完成,但下面的 cmets 大约功率稳定性、热平衡等,仍然要求它基本上是一个时钟,只是一个滴答声很长的时钟。
【解决方案3】:

如果没有时钟或对操作系统的参考,您将无法测量与外部世界相关的任何事物。但是,您当然可以在知道任务是完成方式的 1/3 或其他情况下进行内部测量。但取决于系统负载、CPU 因散热要求而节流、其他程序正在运行等,最后 1/3 可能需要与前 2/3 或更长的时间一样长。您可以应用 huristics 来(仅)对自己加载 balanace 长时间运行的任务,以便例如,如果相对于线程的任务数量发生变化以实现所需的性能特征,那么事情会很顺利,但 PC 必须从某个地方得到它的时间。真正便宜的时钟从功率为 60hz 的事实中获取时间,因此每秒每 60 个周期流逝。但是实际的赫兹数会有所不同,并且可能会在一个方向上不断变化,因此像这样的时钟会很快失去同步,每天几秒,甚至更多。我想通过相机和盒子上的一个洞,您可以确定太阳何时位于天空中的特定位置,并以此确定时间,但我们在这里距离很远。

【讨论】:

    【解决方案4】:

    您主板中的硬件时钟包含一个经过精确调谐的石英晶体,当精确的电流通过它时,它会以 32,768 Hz [2^15] 的频率振动。时钟计算这些振动以标记时间的流逝。系统调用会参考硬件时钟来获取时间,如果没有硬件时钟,您的 PC 根本不会知道在任意执行点之间是否已经过了一秒、一天或一年。

    这就是系统所说的参考,尝试使用其他任何东西都只是徒劳的练习,因为其他所有东西都是计算机的设计目的是根据当时恰好接收到的电压尽可能快地运行.

    您可以尝试计算 CPU 时钟周期,但 CPU 时钟只是设计为根据输入电压尽可能快地振动,并且可以根据负载要求和电源电压的稳定性而变化供应交付是。这使得它作为一种测量时间的方法完全不可靠,因为如果你有一个程序来实时监控时钟速度,你会注意到它通常会不断波动 +/- 几兆赫兹。

    即使是硬件时钟也不可靠,因为施加在晶体上的电压虽然受到严格控制,但仍然是可变的。如果您关闭 NTP 服务和/或将其与 Internet 断开连接,则时间可能会每月甚至每周漂移几分钟。 NTP 服务器参考测量物理基本特性的原子钟,即铯原子的振荡。一秒目前定义为:

    9,192,631,770 个辐射周期的持续时间,对应于铯 133 原子基态的两个超精细能级之间的跃迁。

    哦...这也是由计算机测量的。

    【讨论】:

      【解决方案5】:

      时间通常由操作系统层提供给语言运行时。因此,如果您正在运行在 Windows 环境中编译的 C/C++ 程序,它会询问 Windows 操作系统的时间。如果您在 Linux 机器上运行在 JVM 中执行的 Java 程序,则 Java 程序从 JVM 获取时间,而 JVM 又从 Linux 获取时间。如果您在浏览器中作为 JavaScript 运行,则 Javascript 运行时从浏览器获取时间,浏览器从操作系统获取时间,等等...

      在较低级别,我相信操作系统的时间基于硬件层中经过的时钟周期,然后与您在 BIOS 或操作系统中设置的一些根时间进行比较。

      更新了更多极客细节:

      更抽象地说,如果你的计算机是 1GHz,这意味着它的 cpu 每 1/1Billion(10-9) 秒(周期为从+电压到-电压并返回的单次转换)。计算机中的一切都基于这些转换,因此主板上的硬件计时器可确保这些转换以一致的频率发生。由于这些硬件计时器非常精确,因此它们是对我们使用的日历时间抽象的重要事项“计数”时间的基础。

      我不是硬件专家,但这是我在学校的计算机体系结构课程和构建基本电路方面的最佳理解。

      根据您的编辑进行澄清:

      程序本身并不“知道”它运行的速度有多慢,因此它本身无法准确地跟踪时间的流逝。某些语言可以从操作系统访问诸如“循环计数”和“处理器速度”之类的信息,因此您可以根据这些信息来近似表示时间流逝,而无需使用时间 API。但考虑到你的问题,即使这样也是一种作弊。

      【讨论】:

      • Windows 有时也会通过 Internet 与时间服务器同步。我假设 linux 和 mac 也可以。
      • 是的!好点,我忘了提。这就是您可以处理这样一个事实的方法,即并非每台计算机都有一个原子钟来保持完美的计时。
      • 所以基本上真的没办法,除非你用计算时间的硬件系统。
      • 服务器时间计算时间的方式和操作系统一样,还是更准确?
      • 是的,这就是底线。这也是有道理的,如果您考虑一下,因为程序除了编译时内置的信息或运行时外部源告诉它的信息外,什么都不知道。服务器时间通常作为一种服务提供,其中硬件为许多其他计算机提供它,因此由于规模经济,可以证明使用更昂贵/更精确的硬件是合理的。此外,如果需要非常精确的时间,您可以使用如下内容:en.wikipedia.org/wiki/Atomic_clock
      【解决方案6】:

      我认为您在某种程度上回答了您自己的问题:“时间是一个如此抽象的概念”。所以我认为这取决于你到底想测量什么?如果是算法效率,我们不关心具体的时间度量,只关心算法相对于输入数量需要多长时间(大 O 表示法)。地球绕它的轴自转需要多长时间还是其中的一小部分,那么显然你需要计算机外部的一些东西来告诉它一次迭代何时开始,然后一次结束,忽略计算机应该做的 cpu 时钟漂移很好地告诉你一天中的几点。

      【讨论】:

        【解决方案7】:

        简单地说,你不能。没有纯粹的软件计时方式。

        每台计算机都有许多不同的硬件计时器。这些一旦触发就会触发中断,这就是处理器本身可以跟踪时间的方式。如果没有这些或其他一些外部来源,您将无法跟踪时间。

        【讨论】:

        • “没有纯软件的计时方式”——这不是 100% 正确的。如果您有网络访问权限,您可以查询 NTP 服务器或类似的东西。是的,我知道服务器使用硬件,但如果您的(嵌入式?)客户端没有时间硬件,这可能是一种解决方法。
        • 这不是真正的解决方案。它会在那个确切的时刻为您提供时间,但是随着时间的流逝,您仍然无法增加时间。除非您依靠远程服务器尽可能快地继续向您发送更新时间的数据包。
        • 所有计算机都有某种形式的内部时钟;没有一个,他们就无法轻松操作。然而,一些内部时钟非常不准确。如果计算机在关闭时不保持一天中的时间,那么在启动时它不知道现在是什么时间。这可以通过查询 NTP 服务器来解决。内部时钟可用于维护(可能不准确)一天中的时间,并通过定期 NTP 查询来防止它过于不同步。但请注意,我只是在扯头发。我同意现代计算机很可能会依赖时钟硬件。
        猜你喜欢
        • 2011-01-29
        • 2011-03-06
        • 1970-01-01
        • 2020-12-29
        • 1970-01-01
        • 1970-01-01
        • 2011-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多