Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid aliasing and improve performance?

Tags:

c++

c++11

In this Stack Overflow answer it is demonstrated that aliasing in C++ can slow down your code. And aliasing in C++ doesn't only apply to pointers, it applies also to references, and more generally to these types specified by the standard. Particularly, there is

an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)

So according to my understanding, if I have code like below,

 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;
   }
 }

and it is possible that a0 can alias one of the elements in array, also possibly alias size because of the aforementioned quote, so a0 and size have to be loaded for each iteration resulting in a performance drop.

  1. Then my question is what should I do to the code to avoid the aliasing, and improve the performance?
  2. Passing by const & won't help since it won't avoid aliasing as specified by the standard. Pass a0 by value? But this will make a copying of a0 which I don't like, since in practice, class A may be very complex and copying is a very expensive option.
  3. Is there a general solution to avoid aliasing in C++? If yes, what is it?
like image 579
Allanqunzi Avatar asked Jul 24 '15 02:07

Allanqunzi


People also ask

How can aliasing be avoided?

The solution to prevent aliasing is to band limit the input signals—limiting all input signal components below one half of the analog to digital converter's (ADC's) sampling frequency. Band limiting is accomplished by using analog low-pass filters that are called anti-aliasing filters.

How do you deal with aliasing?

Aliasing is generally avoided by applying low-pass filters or anti-aliasing filters (AAF) to the input signal before sampling and when converting a signal from a higher to a lower sampling rate.

What is aliasing in computer science?

Aliasing: Aliasing refers to the situation where the same memory location can be accessed using different names. For Example, if a function takes two pointers A and B which have the same value, then the name A[0] aliases the name B[0] i.e., we say the pointers A and B alias each other.

What is aliasing in videos?

Sometimes called moiré or a glitch, aliasing is a phenomenon where a digital camera has trouble translating an intricate pattern. Aliasing can result in a number of odd visual artifacts in photos or videos.


2 Answers

The issue of avoiding aliasing performance issue in C++ seems to be covered by Evolution Working Group issue 72: N4150 Alias-Set Attributes: Toward restrict-like aliasing semantics for C++, N3988 Towards restrict-like aliasing semantics for C++ N3635 Towards restrict-like semantics for C++ and N4150 was the latest version of the proposal. The EWG issue is not yet resolved but apparently is considered ready for review.

The proposal proposes C like restrict qualifiers which currently are supported by extensions in C++ by many compilers but have fuzzy areas, the proposal says amongst other things:

There is no question that the restrict qualifier benefits compiler optimization in many ways, notably allowing improved code motion and elimination of loads and stores. Since the introduction of C99 restrict, it has been provided as a C++ extension in many compilers. But the feature is brittle in C++ without clear rules for C++ syntax and semantics. Now with the introduction of C++11, functors are being replaced with lambdas and users have begun asking how to use restrict in the presence of lambdas. Given the existing compiler support, we need to provide a solution with well-defined C++ semantics, before use of some common subset of C99 restrict becomes widely used in combination with C++11 constructs.

the proposal also notes:

Without standardizing and improving the existing C99 restrict facility in C++, users typically have to jump through considerable hoops to get its effect through code rewriting through temporaries, or factoring and inlining function bodies to simulate its effect.

So it seems like there is currently no good solution, although current compilers have extensions which offer C restrict like semantics there are a lot of grey areas section 3. Issues with restrict in C++ and C covers some of the methods used to avoid aliasing but they all have flaws.

The proposal mentioned N3538 which mentions some of the techniques and flaws associated with these techniques. For example:

The simplest technique to overcoming aliasing is to copy the potentially aliasing parameter.

void rf2(type& output, const type& input) {
    type temp = input;
    output += ra1(temp);
    output += ra2(temp);
}

This technique is both more complex and less efficient than simply passing the parameter by value. While the technique can be useful when dealing with legacy interfaces, it should not be a primary technique.

This technique would apply to your case.

Note for interesting take on aliasing and the C99 restrict qualifier On the redundancy of C99's restrict.

like image 148
Shafik Yaghmour Avatar answered Oct 23 '22 23:10

Shafik Yaghmour


If the intent is that you are not expecting size or a0.val to change during the execution of foo, then you can make that explicit by having these be local values:

void foo(vector<A> & array, int size, const A & a0) {
    auto new_val = 2*a0.val;
    for(int i=0;i<size;++i) {
        array[i].val = new_val;
    }
}

Now it is clear that you are intending to set all the elements to the same value. It is clear to the reader as well as the compiler.

like image 37
Vaughn Cato Avatar answered Oct 23 '22 23:10

Vaughn Cato