2

这听起来像是一个奇怪的问题,但是你怎么能不使用编程语言的 API 来编程时间呢?时间是一个如此抽象的概念,如果不使用预定义的时间函数,你怎么能编写程序呢?

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

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

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

4

7 回答 7

8

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

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

更新了更多极客细节:

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

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

根据您的编辑澄清:

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

于 2013-09-13T18:47:54.980 回答
5

简单地说,你不能。没有纯软件的方式来告诉时间。

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

于 2013-09-13T18:43:39.273 回答
5

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

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

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

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

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

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

于 2013-09-13T19:34:40.653 回答
2

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

于 2013-09-13T19:54:54.683 回答
2

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

System.currentTimeMillis();

这被实现为

public static native long currentTimeMillis();

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

于 2013-09-13T18:47:16.897 回答
1

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

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

参考:宇宙射线:它们影响程序的概率是多少?

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

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

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

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

不过,确实有可能……

于 2013-09-15T02:25:12.007 回答
1

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

于 2013-09-13T18:58:56.180 回答