-7

我将在我的 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
          }
4

2 回答 2

4

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

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

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

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

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

  • 您是否在后台运行其他进程?
  • 您是否使用相同的技术来衡量两种情况下的性能?
  • 您是否收集了足够的样本(并且您是否进行了数学证明)?
于 2013-08-22T04:44:32.330 回答
0

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

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

您是生成 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 运行的外部循环,以便现在嵌套三个循环。与 25 秒相比,时间现在应该是 55 秒。

于 2013-08-22T06:24:51.843 回答