当试图让循环进行自动矢量化时,我看到过这样的代码:
void addFP(int N, float *in1, float *in2, float * restrict out)
{
for (i = 0 ; i < N; i++)
{
out[i] = in1[i] + in2[i];
}
}
需要使用restrict关键字时,请向编译器保证指针别名,以便它可以向循环进行矢量化。
这样的事情会做同样的事情吗?
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];
}
}
如果这确实有效,哪个更便携?
tl; dr可以使用std :: unique_ptr替换你试图自动矢量化的循环中的restrict关键字吗?
答案 0 :(得分:2)
restrict
is not part of C++11,而它是C99的一部分。
std::unique_ptr<T> foo;
告诉你的编译器:我只需要这个范围内的内存。一旦此范围结束,释放内存。
restrict
告诉你的编译器:我知道你无法知道或证明这一点,但是我发誓说这是对这个内存块的唯一引用功能
unique_ptr
不会停止别名,编译器也不会认为它们不存在:
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
所以你的第一个版本在C ++ 11中无效(虽然它适用于许多现代编译器),第二个版本没有进行你期望的优化。仍然得到行为concider std::valarray
。
答案 1 :(得分:1)
我不这么认为。假设这段代码:
auto p = std::make_unique<float>(0.1f);
auto raw = p.get();
addFP(1, raw, raw, std::move(p));