问题标签 [restrict-qualifier]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 限制限定符的详细但可读的解释?
我终于对 C99 的一些特性产生了兴趣,但现在我无法理解 C99 草案的相关部分。
我知道restrict 是一个承诺,即两个restrict 限定的指针不会指向同一个对象,但是我对什么是允许的和不允许的内容的更详细和具体的解释的尝试很少出现。
所以我的问题是:有人可以提供关于限制指针的详细信息的可读、可理解的解释,例如我什么时候可以和不能使用它们,什么时候是 UB 等等。越详细越好。我厌倦了看着 C99 草案让我头疼。
谢谢。
c - 函数原型中的顶层 volatile 或 restrict 是否重要?
以下原型之间有什么实际区别吗?
C11 6.7.6.3/15 部分(最后一句)说,为了确定类型兼容性,不考虑顶级限定符,即允许函数定义在其参数上具有与原型不同的顶级限定符宣言了。
但是(与 C++ 不同)它并没有说它们被完全忽略。在这种情况下const
显然没有实际意义;但是,在 和 的情况下volatile
,restrict
可能会有所不同。
例子:
原型中的存在是否允许编译器优化forrestrict
的读取?a
return a;
(相关问题)
c99 - 将限制限定符与 C99 可变长度数组 (VLA) 一起使用
我正在探索 C99 中简单循环的不同实现如何根据函数签名自动矢量化。
这是我的代码:
当我编译时
我看到 VLA 案例不是自动矢量化的,但是当我添加标志来断言 no aliasing-fno-alias
时,它们是。因此,我得出结论,我应该在源代码中规定这个,所以我尝试通过编译来做到这一点
编译器错误输出包括
但如您所见,我的 VLA 参数不允许使用限制。
所以我的问题是:有没有办法在 ISO C 中断言 VLA 没有别名?
请注意,我可以使用编译指示在源代码中断言没有别名 - 例如simd
,omp simd
等ivdep
- 并获得我想要的自动矢量化,但这些不是 ISO C。
在这种情况下,ISO C 是指 C 的最新版本,在撰写本文时当然是 C11。
c - 'restrict' 关键字 - 为什么允许从外部受限变量分配给内部受限变量?
首先是一些参考资料。C99 标准在第restrict
6.7.3 节中对此进行了说明:
通过限制限定指针访问的对象与该指针具有特殊关联。这种关联,在下面的 6.7.3.1 中定义,要求对该对象的所有访问都直接或间接地使用该特定指针的值。117)
restrict
限定符(如存储类)的预期用途register
是促进优化,并且从构成符合程序的所有预处理翻译单元中删除限定符的所有实例不会改变其含义(即,可观察的行为)。
然后(§6.7.3.1“正式定义restrict
”):
让
D
是一个普通标识符的声明,它提供了一种将对象指定P
为指向 type 的限制限定指针的方法T
。如果
D
出现在块内并且没有存储类extern
,B
则表示该块。如果D
出现在函数定义的参数声明列表中,letB
表示关联的块。否则,让B
表示 main 块(或在独立环境中程序启动时调用的任何函数块)。在下文中,指针表达式
E
被称为是基于对象的P
,如果(在执行 的某个序列点,在计算B
之前E
)修改P
为指向它以前指向的数组对象的副本将改变 的值E
. 119)请注意,“基于”仅针对具有指针类型的表达式定义。在 的每次执行期间
B
,让成为基于 的L
任何左值。如果用于访问它指定的对象的值,并且也被修改(通过任何方式),则适用以下要求:不应该是 const 限定的。用于访问 的值的每个其他左值也应具有基于 的地址。就本条而言,修改的每个访问也应被视为修改。如果分配了一个指针表达式的值,该指针表达式基于另一个与块关联的受限指针对象,则要么执行&L
P
L
X
X
T
X
P
X
P
P
E
P2
B2
B2
应在 的执行之前开始B
,或 的执行B2
应在转让之前结束。如果不满足这些要求,则行为未定义。
正如一些人指出的那样,这说明了规则(标准中的示例 4):
现在,我的第一个问题是:为什么可以从外部受限指针分配给内部受限指针?
我的理解是没有什么可以禁止的,它有明显的别名:
当然,别名集仅限于两个指针。
因此我的第二个问题是:从外部分配到内部(允许),而不是从内部分配到外部(禁止,例如p1 = q1;
在上面的第一个示例中)有什么区别?
c - 如果指针完全相同,C++ 指针别名是否构成威胁?
考虑这个用于矢量化的函数:
如果 src & dst 当然没有别名,这将起作用。但是如果 src == dst 呢?像 src == dst+1 这样的极端情况当然是不允许的。但是,如果指针相同,则应该没有问题,还是我遗漏了什么?
编辑:restrict 是 Intel C++ 编译器关键字,MSVC 有 __restrict。
我对这个问题的看法是,我看不出任何一种矢量化如何出错:由于每个 dst 值都依赖于完全不同(没有任何别名)或完全相同地址的单个 src 值,当dst 改变了,src 值就不再需要了,因为它已经被写入意味着输出已经被计算了。唯一的情况是编译器将 dst 本身用作临时缓冲区,我认为这甚至不正确。
c++ - 我可以以某种方式`__restrict__ this`吗?
我一直在看Mike Acton 在 CppCon 2014 上关于 C++ 中面向数据的设计的演讲,他举了这个例子:
并解释了一些编译器如何在每次迭代中不断重新读取m_someDataMemberOfFoo
,可能是因为它的值可能会由于并发访问而改变。不管编译器这样做是否合适——是否可以告诉编译器在执行某些方法期间专门忽略任何并发访问任何内容的可能性,以便它可以更好地优化?
换句话说,我可以告诉它this
是__restrict__
ed 的编译器吗?
c - 限制关键字不起作用?
我正在使用带有 C99 标准的 mingw32-gcc。restrict
我在下面的代码中粘贴了一些关于关键字的文章的编辑- http://wr.informatik.uni-hamburg.de/_media/teaching/wintersemester_2013_2014/epc-1314-fasselt-c-keywords-report.pdf。根据作者的说法,"Result One"
应该"Result Two"
是不同的,但是当我运行它时,它们是相同的。我没有收到任何编译器警告。有没有我遗漏的设置?
c - `restrict` 是否会影响传递的指针的别名,而不是彼此
添加到 C99 中的关键字的主要用途之一restrict
是允许编译器将某些内容加载到寄存器中,并假设该寄存器将镜像由此加载的变量的状态。给定
编译器有权假设写入(*b)
不会受到影响(*a)
,从而避免(*a)
在它之后重新加载。restrict
对混叠有任何其他影响吗?例如,给定:
编译器是否需要预测 的增量,以及对and*q
的调用都可能受到干扰,并且调用可能对and的值“感兴趣” ?是否需要编译器假设调用可能已经持久化了它的参数——即使它被标记了,这样可以修改?foo2a()
foo2b()
x
x
*q
foo2a()
restrict
foo2b()
z
如果编译器需要在最坏情况的假设下运行,尽管有restrict
关键字,是否有任何方法可以授予编译器权限以忽略在函数调用之前存储对某些变量的任何更改并在下次重新加载它的任何正常义务需要吗?
c - 声明的参数限制和编译器警告
gcc 5 和 clang 3.6 都不会在restrict
限定符的约束被违反时给出警告,即使在调用时也是如此-Wall
。考虑以下代码片段:
天真地,我希望可以静态确定违规行为,并且我希望这-Wall
会发出警告。我是否错过了某处的标志,或者发出我没有看到的警告是否有问题?
cuda - const * __restrict__ 可以增加 cuda 寄存器的使用吗?
因为我的指针都指向不重叠的内存,所以我全力以赴,替换了传递给内核(及其内联函数)的指针,使其成为受限的,并尽可能使它们成为 const。然而,这增加了某些内核的寄存器使用量并减少了其他内核的使用量。这对我来说没有多大意义。
有谁知道为什么会这样?