3

When trying to get loops to auto-vectorise, I've seen code like this written:

void addFP(int N, float *in1, float *in2, float * restrict out)
{
    for (i = 0 ; i < N; i++)
    {
         out[i] = in1[i] + in2[i];
    }
}

Where the restrict keyword is needed reassure the compiler about pointer aliases, so that it can vectorise the loop.

Would something like this do the same thing?

void addFP(int N, float *in1, float *in2, std::unique_ptr<float> out)
{
    for (i = 0 ; i < N; i++)
    {
         out[i] = in1[i] + in2[i];
    }
}

If this does work, which is the more portable choice?

tl;dr Can std::unique_ptr be used to replace the restrict keyword in a loop you're trying to auto-vectorise?

Theolodus
  • 2,004
  • 1
  • 23
  • 30
  • `unique_ptr` points to a single `float`. (I think you can do `unique_ptr` instead) – M.M Mar 17 '15 at 11:47

2 Answers2

2

restrict is not part of C++11, instead it is part of C99.

std::unique_ptr<T> foo; is telling your compiler: I only need the memory in this scope. Once this scope ends, free the memory.

restrict tells your compiler: I know that you can't know or proof this, but I pinky swear that this is the only reference to this chunk of memory that occurs in this function.

unique_ptr doesn't stop aliases, nor should the compiler assume they don't exist:

int* pointer = new int[3];
int* alias = pointer;

std::unique_ptr<int> alias2(pointer);
std::unique_ptr<int> alias3(pointer); //compiles, but crashes when deleting

So your first version is not valid in C++11 (though it works on many modern compilers) and the second doesn't do the optimization you are expecting. To still get the behavior concider std::valarray.

Community
  • 1
  • 1
FirefoxMetzger
  • 2,880
  • 1
  • 18
  • 32
1

I don't think so. Suppose this code:

auto p = std::make_unique<float>(0.1f);
auto raw = p.get();
addFP(1, raw, raw, std::move(p));
ikh
  • 10,119
  • 1
  • 31
  • 70
  • You can do this with `restrict` pointers as well, it’s just not defined what you’ll get. – Jon Purdy Mar 17 '15 at 12:04
  • @JonPurdy Doing this with `restrict` causes undefined behavior, which means that this is virtually forbidden by standard (think about `printf("%s", 42);`). In contrast, my answer's code doesn't and shouldn't make any errors (as far as I know) – ikh Mar 17 '15 at 12:07