优化,编译及其效果

时间:2010-01-04 10:15:05

标签: optimization multicore intel

(i)如果某个CPU类的程序已优化(例如,多核Core i7)        通过编译相同的代码,然后将其性能        在老一代的其他CPU上处于次优水平(例如Pentium 4)        ...优化可能会对其他CPU的性能造成损害..?

(ii)为了优化,编译器可以使用x86扩展(如SSE 4)        在较旧的CPU中不可用....所以,是否存在对某些非扩展的回落        基于旧CPU的基础例程..?

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

(iv)真正的多核螺纹应用程序是否能有效地发挥作用        较旧的CPU(如奔腾III或4)..?

4 个答案:

答案 0 :(得分:2)

  1. 在CPU X上优化执行代码可能会使得代码在CPU Y上的优化程度低于为在Y Y上执行而优化的相同代码。可能。

  2. 可能不是。

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

  4. 可能不是。

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

答案 1 :(得分:2)

在平台上编译并不意味着优化 此平台。 (也许这只是你问题中的错误措辞。)

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

此外,在大多数情况下,优化器避免“非优化”非优化平台,例如:在针对i7进行优化时,如果对于另一个通用平台的主要命中,通常不会选择i7上的小改进。

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

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

  • sequence if (x==c) goto label
  • 范围检查和跳转表
  • 二元搜索
  • 以上
  • 的组合

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

答案 2 :(得分:0)

I)如果你没有告诉编译器喜欢哪种CPU类型,那么它在所有CPU上的可能性都会略微不理想。另一方面,如果您让编译器知道为您的特定类型的CPU进行优化,那么它在其他CPU类型上肯定是次优的。

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

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

IV)如果我们忽略了较新CPU的片上效率和明显的架构差异,那么它可能在较旧的CPU上也能表现出色。多核处理本身并不依赖于CPU类型。但性能非常依赖于机器架构(例如:内存带宽,NUMA,芯片到芯片总线),以及多核通信的差异(例如:高速缓存一致性,总线锁定机制,共享高速缓存)。所有这一切使得无法比较MP中较新和较旧的CPU效率,但这并不是您所相信的。因此总的来说,为较新的CPU制作的MP程序不应该低效地使用旧CPU的MP方面。或者换句话说,仅仅针对较旧的CPU调整程序的MP方面也不会有太大作用。显然你可以重写你的算法以更有效地使用特定的CPU(例如:共享缓存可能允许你使用在工作线程之间交换更多数据的算法,但是这个算法会死在没有共享缓存,完全总线锁定的系统上和低内存延迟/带宽),但它涉及的不仅仅是与MP相关的调整。

答案 3 :(得分:0)

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

(2)银行对你的二进制文件失败或崩溃。有时候你很幸运,大部分时间你都没有。有新的指令是的,并且支持它们可能意味着陷阱未定义的指令并且具有该指令的软件仿真,该指令将非常慢并且对它的需求不足意味着它可能做得不好或者不存在。优化可以使用新的指令,但不仅仅是我猜你正在讨论的大部分优化都与重新排序指令有关,这样各种管道都不会停滞。所以你安排它们在一代处理器上快速运行它们会慢一些,因为在x86系列中核心变化太大了。 AMD有一段时间的良好运行,因为他们会使相同的代码运行得更快,而不是试图发明新的处理器,当软件赶上时最终会更快。不再是真的,amd和intel都在努力让芯片保持运转而不会崩溃。

(3)一般来说,是的。例如,gcc是一个可怕的编译器,一个尺寸适合所有人都不适合,它永远不会,也永远不会有任何优化。例如,gcc 4.x代码在同一处理器的gcc 3.x代码上较慢(是的,所有这些都是主观的,这完全取决于正在编译的特定应用程序)。我使用的内部编译器在廉价或免费之前是跳跃式的(我不限于此处的x86)。它们是否物有所值?这是个问题 一般来说,由于可怕的新编程语言和内存,存储,高速缓存层次,软件工程技能都处于历史最低水平。这意味着能够制作出良好编译器的工程师池,而不是一个好的优化编译器会随着时间的推移而减少,这已经持续了至少10年。因此,即使是内部编译器也会随着时间的推移而降级,或者他们只是让他们的员工继续工作并为开源工具做出贡献,而不是使用内部工具。此外,硬件工程师使用的工具也因同样的原因而降级,因此我们现在拥有处理器,我们希望它们能够在不崩溃的情况下运行,而不是尝试进行优化。有许多错误和芯片变化,大多数编译器工作是避免错误。最重要的是,gcc单独摧毁了编译器世界。

(4)见上文(2)。不要银行。您想要运行此操作系统的操作系统可能无法安装在旧处理器上,从而为您节省了成本。出于同样的原因,针对您的奔腾III优化的二进制文件在Pentium 4上运行速度较慢,反之亦然。编写为在多核处理器上运行良好的代码在单核处理器上的运行速度比为单核处理器优化相同的应用程序要慢。

问题的根源是x86指令集很可怕。这么多优秀的指令集已经出现,不需要硬件技巧来使它们每一代都更快。但是wintel机器创造了两个垄断,其他人无法进入市场。我的朋友们一直在提醒我,这些x86机器是微编码的,所以你真的没有看到里面的指令集。令我更加愤怒的是,可怕的isa只是一个解释层。它有点像使用Java。只要知识保持在最高位置,你在问题中提出的问题就会继续存在,如果替代品没有成为垄断者,那么我们将永远陷入Java模型中,在这种模式中你是一方或另一方的共同点,要么您可以模拟特定硬件上的通用平台,或者您正在编写应用程序并编译到通用平台。