当我将遗留代码、库代码或示例代码集成到我自己的代码库中时,我想知道如何通过重新散列源代码来避免浪费我的时间和冒着输入错误的风险。
如果我给出一个基于图像处理场景的简单示例,您可能会明白我的意思。
发现我正在集成这样的代码片段实际上并不罕见:
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];
}
}
随着时间的推移,我已经习惯于做一些事情,比如将不必要的计算移出内部循环,并可能将后缀增量更改为前缀......
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];
}
}
或者,我可以使用指针算术,或者按行...
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];
}
}
...或按行和列...所以我最终得到了这样的结果
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;
}
现在,当我从头开始编写时,我会习惯性地应用自己的“优化”,但我知道编译器也会执行以下操作:
- 将代码从内部循环移动到外部循环
- 将后缀增量更改为前缀
- 还有很多我不知道的东西
请记住,每次我以这种方式处理一段工作、经过测试的代码时,我不仅会花费自己一些时间,而且还会冒着引入手指问题或其他错误的风险(上面的示例已简化)。我知道“过早的优化”以及通过设计更好的算法等来提高性能的其他方法,但是对于上述情况,我正在创建将在更大的流水线类型的应用程序中使用的构建块,我可以' t 预测非功能性需求可能是什么,所以我只希望代码在时间限制内尽可能快和紧凑(我的意思是我花在调整代码上的时间)。
所以,我的问题是:我在哪里可以找到“现代”编译器通常支持的编译器优化。我正在使用 Visual Studio 2008 和 2012 的混合版本,但我很想知道与替代品是否存在差异,例如英特尔的 C/C++ 编译器。谁能提供一些见解和/或指向我有用的网络链接、书籍或其他参考资料?
编辑
只是为了澄清我的问题
- 我上面展示的优化只是简单的示例,而不是完整的列表。我知道进行这些特定更改是没有意义的(从性能的角度来看),因为编译器无论如何都会这样做。
- 我专门寻找有关我正在使用的编译器提供了哪些优化的信息。