4

(i) 如果一个程序通过在同一个 CPU 类别(例如 Multi-Core Core i7) 上编译来优化,那么它的性能在老一代的其他 CPU(例如 Pentium 4)上会处于次优水平。 .. 优化可能对其他 CPU 的性能有害..?

(ii) 为进行优化,编译器可能会使用旧 CPU 中不可用的 x86 扩展(如 SSE 4)......那么,是否有回退到旧 CPU 上的一些基于非扩展的例程......?

(iii) 英特尔 C++ 编译器是否比 Visual C++ 编译器或 GCC 更优化?

(iv) 真正的多核线程应用程序能否在较旧的 CPU(如 Pentium III 或 4)上高效运行..?

4

4 回答 4

2
  1. 与在 CPU Y 上执行优化的相同代码相比,优化在 CPU X 上执行的代码可能会使该代码在 CPU Y 上的优化程度降低。可能是这样。

  2. 可能不是。

  3. 无法一概而论。你必须测试你的代码并得出你自己的结论。

  4. 可能不是。

对于在某些条件下(编译器的选择、CPU 的选择、编译的优化标志的选择)为什么 X 应该比 Y 快的每个论点,一些聪明的 SOer 会找到一个反论点,对于每个示例都是一个反例。当橡胶遇到道路时,您唯一的办法就是测试和测量。如果您想知道编译器 X 是否比编译器 Y“更好”,请先定义您的意思,然后进行大量实验,然后分析结果。

于 2010-01-04T10:27:24.743 回答
2

一个平台上编译并不意味着针对这个平台进行优化。(也许这只是你问题中的措辞不好。)

在我使用的所有编译器中,针对平台 X 的优化不会影响指令集,只会影响它的使用方式,例如针对 i7 的优化不会启用 SSE2 指令。

此外,在大多数情况下,优化器会避免“悲观”未优化的平台,例如在针对 i7 进行优化时,如果 i7 上的小幅改进意味着对另一个常见平台的重大影响,则通常不会选择 i7 。

这还取决于指令集的性能差异——我的印象是它们在过去十年中变得越来越少(但我最近没有深入研究——对于最新一代来说可能是错误的)。还要考虑优化仅在少数地方产生显着差异。

为了说明优化器的可能选项,请考虑以下方法来实现 switch 语句:

  • 序列if (x==c) goto label
  • 范围检查和跳转表
  • 二分查找
  • 以上结合

“最佳”算法取决于比较、固定偏移量跳转和跳转到从内存读取的地址的相对成本。它们在现代平台上没有太大区别,但即使是很小的差异也会产生对一种或其他实现的偏好。

于 2010-01-04T21:46:29.637 回答
0

(1) 不仅有可能,而且几乎每一代 x86 处理器都记录了它。回到 8088,继续前进,每一代人。对于当前主流应用程序和操作系统(包括 Linux),较新的处理器的时钟速度较慢。32 位到 64 位的转换没有帮助,更多的内核和更低的时钟速度使情况变得更糟。出于同样的原因,倒退也是如此。

(2) 依靠你的二进制文件失败或崩溃。有时你很幸运,大多数时候你没有。有新的指令是的,并且支持它们可能意味着捕获未定义的指令并对该指令进行软件仿真,这将非常缓慢并且缺乏对它的需求意味着它可能做得不好或根本不存在。优化可以使用新指令,但不仅仅是我猜你正在谈论的大部分优化与重新排序指令有关,这样各种管道就不会停止。因此,您将它们安排在一代处理器上速度很快,而在另一代处理器上它们会变慢,因为在 x86 系列中,内核变化太多。AMD 在那里运行了一段时间,因为他们会让相同的代码运行得更快,而不是试图发明新的处理器,最终在软件赶上时会更快。amd 和英特尔都在努力保持芯片运行而不崩溃,这不再是真的。

(3) 一般情况下,是的。例如 gcc 是一个糟糕的编译器,一种尺寸适合所有人,没有人适合,它永远不会也永远不会擅长优化。例如,gcc 4.x 代码在同一处理器的 gcc 3.x 代码上较慢(是的,所有这些都是主观的,这完全取决于正在编译的特定应用程序)。我使用的内部编译器比廉价或免费的编译器有了飞跃式发展(我在这里并不局限于 x86)。它们值这个价吗?就是那个问题。
一般来说,由于可怕的新编程语言和大量的内存、存储、缓存层,软件工程技能一直处于低位。这意味着能够使一个好的编译器更不用说一个好的优化编译器的工程师库随着时间的推移而减少,这种情况已经持续了至少 10 年。因此,即使是内部编译器也会随着时间的推移而退化,或者他们只是让员工致力于开源工具并为开源工具做出贡献,而不是拥有内部工具。同样的原因,硬件工程师使用的工具也在退化,所以我们现在有处理器,我们希望只是运行而不会崩溃,而不是尝试优化。有如此多的错误和芯片变化,大多数编译器的工作都是在避免这些错误。归根结底,gcc 单枪匹马地摧毁了编译器世界。

(4) 见上文 (2)。不要指望它。您想要运行它的操作系统可能无论如何都不会安装在较旧的处理器上,从而为您省去痛苦。出于同样的原因,为您的 pentium III 优化的二进制文件在您的 Pentium 4 上运行较慢,反之亦然。为在多核处理器上运行良好而编写的代码在单核处理器上的运行速度比在单核处理器上优化相同应用程序时要慢。

问题的根源在于 x86 指令集是可怕的。已经出现了如此多的高级指令集,它们不需要硬件技巧就可以使它们每一代都更快。但是wintel机器造成了两个垄断,其他的都无法进入市场。我的朋友一直提醒我,这些 x86 机器是微编码的,所以你真的看不到里面的指令集。更让我愤怒的是,可怕的 isa 只是一个解释层。这有点像使用 Java。只要英特尔保持领先地位,您在问题中概述的问题就会继续存在,如果替代品没有成为垄断者,那么我们将永远陷入 Java 模型中,您要么是公分母的一方,要么是另一方您在特定硬件上模拟通用平台,

于 2010-01-07T04:18:57.673 回答
0

I) 如果您没有告诉编译器支持哪种 CPU 类型,那么它很可能在所有 CPU 上都不是最优的。另一方面,如果您让编译器知道要针对您的特定类型的 CPU 进行优化,那么它在其他 CPU 类型上肯定是次优的。

II) 否(至少对于英特尔和 MS)。如果您告诉编译器使用 SSE4 进行编译,则无需测试即可在代码中的任何位置使用 SSE4 感到安全。确保您的平台能够执行 SSE4 指令成为您的责任,否则您的程序将崩溃。您可能想要编译两个库并加载正确的库。为 SSE4(或任何其他指令集)编译的替代方法是使用内部函数,它们将在内部检查性能最佳的指令集(以轻微的开销为代价)。请注意,我在这里不是在谈论指令内在函数(那些特定于指令集),而是内在函数。

III)这本身就是另一个讨论。它随每个版本而变化,并且对于不同的程序可能会有所不同。所以这里唯一的解决方案是测试。只是一个注释;众所周知,Intel 编译器不能很好地编译以在 Intel 以外的任何设备上运行(例如:内部函数可能无法识别 AMD 或 Via CPU 的指令集)。

IV) 如果我们忽略较新 CPU 的片上效率和明显的架构差异,那么是的,它可能在较旧的 CPU 上表现得一样好。多核处理本身不依赖于 CPU 类型。但是性能很大程度上取决于机器架构(例如:内存带宽、NUMA、芯片到芯片总线)和多核通信的差异(例如:缓存一致性、总线锁定机制、共享缓存)。所有这一切都使得在 MP 中比较新旧 CPU 效率变得不可能,但我相信这不是你要问的。所以总的来说,为较新的 CPU 制作的 MP 程序不应该降低旧 CPU 的 MP 方面的使用效率。或者换句话说,仅仅针对较旧的 CPU 调整程序的 MP 方面不会有太大的作用。

于 2010-01-05T16:51:17.720 回答