【问题标题】:Integer determinism [closed]整数确定性[关闭]
【发布时间】:2013-02-18 22:13:31
【问题描述】:

我只想问,整数是确定性的吗?我知道它们应该是,但它们在所有平台上都相同吗?

我在 Google 上进行了搜索,但它返回的唯一内容是如何将两个数字放在一起,以及对确定性主题的深入研究。

我之所以问这个问题是因为我正计划开发一个具有锁步网络模型的小型演示。屏幕上会有几个块可以通过命令移动,并且正在考虑为所有块赋予整数值。

这也让我想到了通常的 RTS 游戏,它们总是不得不与浮点数不同步(这不是它们不同步的唯一原因,但仍然是不同步的主要因素)。为什么这些游戏不只使用 64 位整数来存储所有单位位置等。我认为 64 位具有存储大量不同值的能力足以处理单位位置等。

【问题讨论】:

  • 计算机中的几乎所有内容在某种程度上都是确定性的。唯一的例外是与时间相关的问题(以及读取/dev/random 的结果,如果您的系统有)。
  • “我只是想问一下,整数是确定性的吗?” - 我认为这里的术语有问题。在整数方面,没有什么比浮点精度的限制更重要,没有。
  • 确定性?以什么方式?好奇的 ?您想要对象的唯一 ID(不可重复)?
  • @EdS 我认为他的意思是定义明确并且具有跨运行/平台的可重现行为
  • 是的,就是这样,我想将用户命令从一个进程发送到所有其他对等连接的进程,并让它们执行完全相同的命令。所以基本上会有一个移动命令,当一个键被按下时会发送。在本地机器上,这会移动块(将其位置存储在一个整数中),所有其他对等点都遵循完全相同的步骤。

标签: c++ c cpu cpu-architecture


【解决方案1】:

有一些重要的未定义行为的情况;例如,如果您的表达式生成一个超出范围的有符号整数值,即使作为中间步骤,那么实际上任何事情都可能发生。 (并且“越界”在某种程度上取决于系统;例如,int 不能保证正好是 32 位。)还有一些实现定义行为的情况;例如,负符号整数值的右移是实现定义的,这意味着编译器可以决定如何处理它,并且必须记录该决定。

当然,在多线程的情况下,除非您注意正确处理同步,否则几乎所有的赌注都会失败。

但是,如果您避免这些情况,那么 - 没有任何平台可以让 2+2 成为除 4 之外的其他东西。

【讨论】:

  • 这是个好消息,我只打算使用加号和减号运算符来更改整数值。另外,我不相信这些值会溢出,因为我打算使用 64 位整数
【解决方案2】:

在某种程度上。只要没有任何运算溢出,算术运算的结果将始终相同。有符号整数溢出的结果是未定义的。即使在程序的同一调用中,编译器优化也可能导致不同的结果。无符号溢出的结果是明确定义的;只要两个平台的 UINT_MAX 值相同,结果将始终相同。您也不能依赖平台使用的实际二进制表示。如果您想在不同机器之间传递整数,则必须使用某种形式的序列化。

【讨论】:

  • +1 表示关于二进制表示(即小端与大端)和序列化的评论。
【解决方案3】:

除了少数罕见的例外(例如,内存访问的计时,以及像 RDRAND 这样的显式随机操作),CPU 上的所有操作都是确定性的,包括整数和浮点操作。

网络游戏中的不同步往往是游戏逻辑错误的结果,而不是架构问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多