关于C/C++编译器优化我能想到什么?

Rog*_*and 8 c++ compiler-optimization visual-c++

我想知道当我将遗留代码,库代码或示例代码集成到我自己的代码库中时,如何通过重新散列源代码来避免浪费我的时间并冒着打字错误.

如果我举一个简单的例子,基于图像处理场景,你可能会看到我的意思.

发现我正在集成这样的代码片段并不罕见:

for (unsigned int y = 0; y < uHeight; y++)
{
    for (unsigned int x = 0; x < uWidth; x++)
    {
        // do something with this pixel ....
        uPixel = pPixels[y * uStride + x];
    }
}
Run Code Online (Sandbox Code Playgroud)

随着时间的推移,我已经习惯于做一些事情,比如从内循环中移除不必要的计算,并可能将后缀增量更改为前缀...

for (unsigned int y = 0; y < uHeight; ++y)
{
    unsigned int uRowOffset = y * uStride;
    for (unsigned int x = 0; x < uWidth; ++x)
    {
        // do something with this pixel ....
        uPixel = pPixels[uRowOffset + x];
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,我可以使用指针算法,按行...

for (unsigned int y = 0; y < uHeight; ++y)
{
    unsigned char *pRow = pPixels + (y * uStride);
    for (unsigned int x = 0; x < uWidth; ++x)
    {
        // do something with this pixel ....
        uPixel = pRow[x];
    }
}
Run Code Online (Sandbox Code Playgroud)

......或者按行和列...所以我最终得到这样的东西

unsigned char *pRow = pPixels;
for (unsigned int y = 0; y < uHeight; ++y)
{
    unsigned char *pPixel = pRow;
    for (unsigned int x = 0; x < uWidth; ++x)
    {
        // do something with this pixel ....
        uPixel = *pPixel++;
    }

    // next row
    pRow += uStride;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我从头开始编写时,我会习惯性地应用自己的"优化",但我知道编译器也将执行以下操作:

  • 将代码从内部循环移动到外部循环
  • 将后缀增量更改为前缀
  • 很多其他我不知道的东西

请记住,每当我以这种方式处理一段正在运行,经过测试的代码时,我不仅花费了一些时间,而且还冒着我会引入手指故障或其他任何问题的风险(以上示例简化了).我知道"过早优化"以及通过设计更好的算法等提高性能的其他方法.但对于上述情况,我正在创建构建块,将用于更大的流水线类型的应用程序,我可以' t预测非功能性需求可能是什么,所以我只希望代码在时间限制内合理快速和紧凑(我的意思是我花时间调整代码).

所以,我的问题是:我在哪里可以找到"现代"编译器通常支持的编译器优化.我正在使用Visual Studio 2008和2012的混合体,但是有兴趣知道是否存在与其他替代品的区别,例如英特尔的C/C++编译器.任何人都可以提供一些见解和/或指向我有用的网站链接,书籍或其他参考?

编辑
只是为了澄清我的问题

  • 我在上面展示的优化是简单的例子,而不是一个完整的列表.我知道(从性能的角度来看)进行那些特定的更改是没有意义的,因为编译器无论如何都会这样做.
  • 我正在寻找有关我正在使用的编译器提供的优化的信息.

NPE*_*NPE 16

我希望您作为示例包含的大多数优化都是浪费时间.一个好的优化编译器应该能够为您完成所有这些.

我可以通过实用建议提出三点建议:

  1. 在处理实际数据的实际应用程序的上下文中分析您的代码.如果你不能,想出一些你认为会模仿最终系统的综合测试.
  2. 只有将通过性能分析证明的代码优化为瓶颈.
  3. 如果您确信某段代码需要优化,那么不要只假设从循环中分解不变表达式会提高性能.始终进行基准测试,可选择查看生成的装配以获得进一步的洞察

以上建议适用于任何优化.但是,最后一点与低级优化特别相关.它们有点像黑色艺术,因为涉及许多相关的架构细节:存储器层次结构和带宽,指令流水线,分支预测,SIMD指令的使用等.

我认为最好依靠对目标体系结构有深入了解的编译器编写器,而不是试图超越它们.

您不时会通过分析找到需要手动优化的东西.然而,这些实例将是相当罕见的,这将允许您在实际上有所作为的事情上花费大量精力.

与此同时,专注于编写正确且可维护的代码.

  • @roger_rowland:关于你的第一条评论,在你能描述之前不要做*任何*.首先,注重正确性和清晰度. (4认同)
  • @roger_rowland你可能意识到过早优化的存在,但你似乎没有意识到你在问如何进行过早优化...... (3认同)