如何避免别名并提高性能?

All*_*nzi 12 c++ c++11

在此Stack Overflow答案中 ,证明了C++中的别名可能会降低代码速度.并且C++中的别名不仅适用于指针,它也适用于引用,更一般地适用于标准指定的这些类型.特别是有

一种聚合或联合类型,包括其成员中的上述类型之一(包括递归地,子聚合或包含联合的成员)

所以根据我的理解,如果我有如下代码,

 class A{
  public:
   int val;
 };

 void foo(vector<A> & array, int & size, A & a0) {
   for(int i=0;i<size;++i) {
    array[i].val = 2*a0.val;
   }
 }
Run Code Online (Sandbox Code Playgroud)

和可能的是,a0可以别名中的元素中的一个array,也可能是别名size由于上述引用的,所以a0size必须装载对于每次迭代导致性能下降.

  1. 然后我的问题是我应该怎么做代码以避免别名,并提高性能?
  2. 传递const &将无济于事,因为它不会避免标准规定的混叠.通过a0按值?但这会使a0我不喜欢的复制,因为在实践中,类A可能非常复杂,复制是一个非常昂贵的选择.
  3. 有没有一个通用的解决方案来避免C++中的别名?如果是,那是什么?

Sha*_*our 7

避免在C++中出现别名性能问题的问题似乎包含在演变工作组问题72:N4150别名集属性:朝向C++的类似于限制的别名语义,N3988迈向C++的类似于限制的别名语义N3635走向类似限制的语义对于C++N4150是该提案的最新版本.EWG问题尚未解决,但显然已准备好进行审核.

该提案提出了C类限制限定符,这些限定符目前由许多编译器在C++中的扩展支持,但具有模糊区域,该提案还说:

毫无疑问,限制限定符在许多方面有利于编译器优化,特别是允许改进的代码运动和消除加载和存储.自从引入C99 restrict以来,它已在许多编译器中作为C++扩展提供.但是这个特性在C++中很脆弱,没有明确的C++语法和语义规则.现在随着C++ 11的引入,函数被lambdas取代,用户已经开始询问如何在lambda存在的情况下使用restrict.鉴于现有的编译器支持,我们需要提供一个具有良好定义的C++语义的解决方案,在使用C99的一些常见子集之前,限制与C++ 11结构一起被广泛使用.

该提案还指出:

如果不对C++中现有的C99限制功能进行标准化和改进,用户通常必须通过临时代码重写来实现其效果,或者通过分解和内联函数体来模拟其效果.

所以似乎目前没有好的解决方案,虽然目前的编译器具有提供C限制的扩展,如语义有很多灰色区域第3.C++和C中的限制问题涵盖了一些用于避免别名的方法但是它们都有缺陷.

该提案提到了N3538,其中提到了与这些技术相关的一些技术和缺陷.例如:

克服别名的最简单方法是复制潜在的别名参数.

void rf2(type& output, const type& input) {
    type temp = input;
    output += ra1(temp);
    output += ra2(temp);
}
Run Code Online (Sandbox Code Playgroud)

与仅通过值传递参数相比,此技术更复杂且效率更低.虽然该技术在处理传统接口时非常有用,但它不应该是主要技术.

这种技术适用于您的情况.

注意有趣的别名和C99限制限定符 关于 C99限制的冗余.