请问有人能为我确认一些别名规则吗?
我知道别名问题(即load-store问题)可能会使以下代码不够优化,因为我们不能假设x,y,z
不重叠:
// case 1:
void plus(size_t n, double *x, double *y, double *z)
{
for (size_t i = 0; i != n; ++i)
z[i] = x[i] + y[i];
}
我知道 C 语言关键字__restrict
可以提示编译器不去考虑重叠的情况,因此可能会生成更好的代码:
// case 2:
void plus(size_t n, double *__restrict x, double *__restrict y, double *__restrict z)
{ // as above... }
但是当我们使用C++风格的代码时,别名如何工作呢?在这种情况下,我们需要处理通过引用传递的容器对象,而不是上面使用原始指针的C语言示例?
例如,如果我们执行以下操作,我认为会出现别名问题:
// case 3:
void plus(std::vector<double> &x, std::vector<double> &y, std::vector<double> &z)
{ // similar to above... }
那么,为了举例说明,如果容器中的基础数据类型不同,是否会有任何区别?在实现层面上,大多数容器使用指针动态管理存储,因此我不清楚编译器如何确保以下内容不重叠:
// case 4:
void foo(std::vector<mytype1> &x, std::vector<mytype2> &y)
{ // interwoven operations on x, y... }
我并不试图进行微小的优化,但我想知道目前将受限制的指针传递到容器中是否比传递引用更好。
编辑:为了澄清一些术语,正如指出的那样:restrict
是C99关键字。各种编译器中还有__restrict
和__restrict__
,但它们都做同样的事情。
&x == &y
,否则我不相信它们会重叠,假设符合标准的向量实现。 - Svenrestrict
是 C 语言的一个关键字(自 C99 起),但__restrict
不是。由于__
的存在,它是编译器的扩展。 - Luc Danton