【问题标题】:CPU takes too much time to execute nested for loop in Linux compare to windows platform [closed]与 Windows 平台相比,CPU 在 Linux 中执行嵌套 for 循环需要花费太多时间 [关闭]
【发布时间】:2013-08-24 16:12:00
【问题描述】:

我将在我的 Linux 平台上运行一个嵌套的 for 循环,大约需要 55 毫秒,而相同的程序可以在 Windows 上运行大约需要 25 毫秒。

Linux 和 Windows 平台的 CPU 配置与 CPU 时钟和 RAM 相比几乎相同。

我还附上了这个问题的代码。

所以,有人知道这里发生了什么或如何优化我将在这台 Linux PC 上运行的嵌套 for 循环吗?

for (i = 0; i < 1944; i += 2)
        for (j = 0; j < 2592; j += 2)
          {
             Here some arithmetic operation is going on
          }

【问题讨论】:

  • 1.我们需要“一些算术运算”。 2. 我们需要您正在使用的编译器名称以及您用来调用它们的参数。 3. 我们需要您用来分析您的代码的代码,以验证其准确性。
  • 除非您提供用于进行性能测试的数学和/或脚本,否则谁能帮助您?
  • “Linux”和“Windows”不是我听说过的 C 编译器的名称。 “Linux 和 Windows 平台的 CPU 配置几乎相同” -- 几乎 相同?
  • 意思是,在基于linux和windows的PC中,CPU时钟和RAM等硬件配置是相同的。
  • “几乎”并不意味着“相同”。但无论如何,请阅读 cmets 和下面的答案,并考虑您的问题被否决的原因。

标签: c linux windows


【解决方案1】:

在这种情况下,Linux 与 Windows 几乎可以肯定是无关的。你是吗

  • 在两个平台上使用相同的编译器?
  • 在两个平台上使用相同版本的编译器?
  • 在两个平台上使用相同的优化设置?

所有这些都会导致结果不同。此外,甚至没有指定 CPU 是否相同。对我的音频采样率转换库进行基准测试,我发现 1.7 GHz Core i5 和 1.6 GHz Atom 之间的吞吐量差异是 6-7 倍。

  • 您是否在两个基准测试中使用相同的硬件

还有许多其他因素会混淆基准,

  • 您是否在后台运行其他进程?
  • 您是否使用相同的技术来衡量两种情况下的性能?
  • 您是否收集了足够的样本(并且您是否进行了数学证明)?

【讨论】:

  • 考虑添加:他是否以可比的方式衡量性能?什么是测量误差?进行了多少次测量,您是否进行了统计比较,例如学生 t 检验或卡方检验?
  • windows编译器是vc++编译器,linux编译器是gcc编译器。
  • 是的。我在两个平台上都使用相同的硬件,并且我还根据该代码编译了一个示例二进制文件,在 linux 上需要 55 毫秒,在 windows 平台上需要 25 毫秒。我没有在后台运行任何其他进程。
  • 我在linux中得到了上述问题的解决方案
  • 感谢支持讨论该问题。
【解决方案2】:

您是否在循环中进行任何函数调用(例如对“math.h”中定义的函数)?

如果是,问题可能是在 GNU 库(在 Linux 中使用)中这些函数的实现效率低于 Windows 库。

您是在生成 32 位还是 64 位可执行文件?比较一个系统上的 64 位可执行文件和另一个系统上的 32 位可执行文件是没有意义的!

如果您安装 32 位运行时库或静态编译,您(通常)可以在 64 位 Linux 下运行 32 位可执行文件。您始终可以在 64 位 Windows 下运行 32 位可执行文件。

如果您不使用函数调用并且 32/64 位也不是问题,您可以通过执行以下操作检查这是否是编译器性能问题:

  • 首先将循环隔离到单个 C 文件中。这意味着:将循环移动到函数“test_loop()”中,并将该函数移动到单独的 C 文件中。
  • 特别是在生成 64 位可执行文件时,该函数不应有任何参数,但所有数据输入和输出都应通过全局变量完成。
  • 获取 GCC for Windows 并使用“-s”选项编译文件 (gcc -o loop.s -S loop.c)。结果将是一个汇编文件。
  • 如果要检查 64 位 Linux,请确保在 Windows 上编译 64 位;如果要检查 32 位 Linux,请确保在 Windows 上编译 32 位
  • 使用 GCC for Windows (gcc -o test.exe test.c loop.s) 编译整个程序并进行运行时测量。
  • 注意:在 32 位 Windows 下,C 编译器会在所有函数名称中添加下划线。因此,在 Linux 下使用汇编文件时,该函数将被命名为“_test_loop()”。全局变量名称(由汇编文件使用)也是如此。您必须调整剩余的 C 文件以在 Linux 下进行编译。 当编译 64 位时,情况并非如此。
  • 在 Linux 下编译程序。不要再次编译包含循环的 C 文件,而是使用 Windows 下生成的汇编文件。将 Linux 上的运行时与 Windows 上的运行时进行比较
  • 使用同一台计算机进行运行时测量;不是两台具有“相似硬件”的计算机

如果现在两个操作系统的运行时相同,那么您会发现这是编译器问题。如果需要Linux下的性能,您可以使用Microsoft编译器在Windows下编译文件并在Linux下使用目标文件。不幸的是,Windows 使用不同于 Linux 的另一种目标文件格式,因此必须将目标文件转换(从 COFF 到 ELF)。

如果在 Windows 下运行时仍然更快,那么问题可能是时间测量的准确性问题。小于 100 毫秒的时间测量通常非常不准确。要检查这一点,您应该创建一个从 0 到 999 运行的外部循环,以便现在嵌套三个循环。时间现在应该是 55 秒,而不是 25 秒。

【讨论】:

  • 通过在 gcc 编译器中设置优化标志,现在我可以在更短的时间内更快地执行嵌套 for 循环。..
猜你喜欢
  • 1970-01-01
  • 2020-04-07
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
相关资源
最近更新 更多