6

我有一个与此类似的函数签名

void Mutliply(const MatrixMN& a, const MatrixMN& b, MatrixMN& out);

在内部,矩阵类有一个float* data;表示m x n组件的。我想告诉编译器,a不要b给输出矩阵加上别名,这样它就不会做大量的加载存储。

我该怎么做呢?我知道我可以传入指向函数签名的指针并用__restrict(在 MSVC 中)标记指针,但我想保留通过引用传递的对象的习语,其中对象包含指向内存的指针。

我也知道这__restrict不适用于对象引用。

4

4 回答 4

2

根据优化器的工作方式,assert(&in1 != &out && &in2 != &out)顶部的 an 可能会起作用。你也可以去掉 out 参数,相信优化器会去掉多余的副本(当然,假设它是一个纯 out 参数)。如果代码是内联的候选代码,编译器可能会看到它自己没有任何别名。如果restrict在引用参数上确实不起作用,您可以对函数调用进行额外的调用,并将所有三个传递给第二个函数,该函数接受适当限制的指针。希望那个会为你内联。

于 2011-06-09T02:32:37.430 回答
1

编写一个带参数的非导出 (file- static, private) 乘法函数,用float*标记参数restrictMultiply调用这个函数。

于 2011-06-09T02:38:46.743 回答
1

由于您似乎对 __restrict 指针感到满意,因此我会使用您所知道的,但您仍然可以包装它并使用引用提供接口:

void Multiply(const MatrixMN& a, const MatrixMN& b, MatrixMN& out) {
  if (&a == &b || &a == &out || &b == &out) {
    // indicate precondition violation however you like
    assert(!"precondition violated");
    abort();  // assert isn't always executed
  }
  else {
    DoMultiply(&a, &b, &out);
  }
}

void DoMultiply(MatrixMN const * __restrict a, MatrixMN const * __restrict b,
              MatrixMN * __restrict out)
{
  //...
}

将指针版本设为“非公开”,例如将其放置在“详细信息”命名空间中,为其提供内部链接(在这种情况下不适用),或为其指定一个特殊名称。你甚至可以使用局部变量而不是参数,并将函数体放在“else”中,但我发现上面的更干净。

于 2011-06-09T02:42:42.247 回答
-1

宏包装器如何在编译时__restrict本身产生效果:(以下是伪代码,未检查):

#define Multiply(A,B,C) Multiply_restrict(&A, &B, &C)

现在中间方法定义为,

inline void Multiply_restrict(const MatrixMN* __restrict pA,
            const MatrixMN* __restrict pB, MatrixMN* __restrict pC)
{
  Multiply_(*pA, *pB, *pC);
}

最后_在你原来的后面加一个Multiply

void Mutliply_(const MatrixMN& a, const MatrixMN& b, MatrixMN& out);

所以最终效果将与您所调用的完全相同:

Multiply(x, y, answer);
于 2011-06-09T02:31:38.197 回答