Can I `__restrict__ this` somehow?

2020-04-18 05:33发布

问题:

I've been watching Mike Acton's talk on Data-oriented design in C++ in CppCon 2014, and he gives this example:

int Foo::Bar(int count)
{
    int value = 0;
    for (int i = 0; i < count; i++) {
        if (m_someDataMemberOfFoo) value++
    }
    return value;
}

And explains how some compilers keep re-reading m_someDataMemberOfFoo in every iteration, perhaps because its value might change due to concurrent access. Regardless of whether it's appropriate for the compiler to do so - can one tell the compiler to specifically ignore any possibility of concurrent access to anything during the execution of some method, so that it may optimize better?

In other words, can I tell it the compiler that this is __restrict__ed?

回答1:

  1. __restrict__ is not standardized in C++, so this question can only be answered on a particular platform. For GCC, you can apply __restrict__ to this in the same way as const:

    void T::fn () __restrict__
    
  2. There is no potential aliasing in your example. C++ specifies undefined behavior for data races.

  3. A new system for C++ restricted pointers is being developed. It will likely be standardized in C++17. Support for this is one of the stated design goals.



回答2:

With the code that you posted, code compiled with any optimisation at all should not re-read that class member. However, take this similar code:

void Foo::Bar(int count, int* result)
{
    *result = 0;
    for (int i = 0; i < count; i++) {
        if (m_someDataMemberOfFoo) (*result)++;
    }
}

In this case, the compiler must assume that result == &m_someDataMemberOfFoo is a possibility, if that member has type int. Obviously any developer calling it the way deserves to get his programming license revoked, but it is legal and the compiler must handle this correctly.

This is even the case if you mark the method as "const". A const method is not allowed to modify any part of *this by using the this pointer (with some exceptions). However, members of *this can be legally modified in other ways if the actual object is not const.

"restrict" in C is intended to fix the problem, and hopefully the same feature in C++ would fix it in this case.