【问题标题】:Why does it take so much longer to loop through 10 billion than 1 billion?为什么循环通过 100 亿比 10 亿需要更长的时间?
【发布时间】:2011-12-27 20:01:20
【问题描述】:

为什么这个循环(到 10 亿)只需要几个声音来执行......

for (i = 0; i < 1000000000; i++)
{

}

...但是这个循环(到 100 亿)需要 >10 分钟?

for (i = 0; i < 10000000000; i++)
{

}

不应该只需要 30 秒左右(3 秒 x 10)吗?

【问题讨论】:

  • 考虑潜在的溢出,也许你的i 是一个 32 位整数?因此,您执行的迭代次数可能与您预期的不同。
  • i的类型是什么?您的目标是 64 位吗?
  • 它可能只是陷入了无限循环。假设i 是一个 32 位整数,它永远不会超过 100 亿。
  • 如果 i 的类型不够大(i
  • @MOleYArd 我宁愿猜他等了 10 分钟并杀死了它(&gt; 也暗示了这一点)。

标签: c loops for-loop


【解决方案1】:

我猜你没有把你的基准测试代码放在这里。原样的代码可能会被编译器优化为根本不运行。也可能是i 溢出,然后您的循环将永远不会结束。

但是,如果您使用i 作为数据结构的索引(特别是如果它是一个数组),那么您的内存分页和数据缓存会极大地影响性能。

【讨论】:

  • 结束 吗?或者你等了 10 分钟就关闭了程序?
  • @nbsp 那么它很可能是由于溢出而导致的无限循环。我很惊讶您没有收到关于此的编译警告。
【解决方案2】:

不同之处在于 1,000,000,000 适合 32 位整数,而 10,000,000,000 适合 64 位。如果它是 32 位的,我会假设它是,它只是溢出,会导致你的循环变得无限。

您的i 是 64 位变量吗?

【讨论】:

【解决方案3】:

我猜i 是一个 32 位整数变量,因此总是小于 100 亿(大于 2^32),而 10 亿仍然适合 32 位范围(大约 2或 40 亿,取决于签名)。虽然不知道编译器是怎么提升这个百亿常量的,但他似乎意识到了溢出问题,让它成为一个无限循环。

当你将i 变成long long int 时会发生什么(也许1000000000010000000000L,但这似乎没问题)?

【讨论】:

  • i 切换为long long 并将10000000000 切换为10000000000L 有效。谢谢。
  • 是的,它在 29 秒内执行。再次感谢。
  • 那是因为 C 中的有符号溢出是未定义的行为,所以允许编译器做任何事情。在这种情况下,它选择loop infinitely,因为它假定值永远不会溢出,这是允许的
【解决方案4】:

如果这对任何人都有帮助:

当 32 位有符号数超出其范围 2^31 - 1 时,该数被解释为负数(由于 2C 格式)。即:

对于 16 位数字:

  0111 1111 1111 1111 (32767)
+ 0000 0000 0000 0001 (1)
---------------------
  1000 0000 0000 0000  (Shoulbe 32769 but instead is -32768)
+ 0000 0000 0000 0001
--------------------
  1000 0000 0000 0001 (-32767)....

所以无限循环是因为您只是在遍历 32 位有符号整数的所有可能值。

【讨论】:

    猜你喜欢
    • 2022-10-25
    • 2019-03-05
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    相关资源
    最近更新 更多