问题标签 [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.
cuda - 如何将 __restrict__ 与 __constant__ 指针指向的数组结合起来?
我认为这将是一个有点时髦的问题,如果我需要详细说明,请说出来。
情况如下:我有大约 2 个 GPU 内存,其中包含我的随机数,我需要在许多不同的功能中使用它们。为了防止将指针从设备函数传递到设备函数(并且如此多次),我将指针放在 gpu 常量内存中,这也为我节省了寄存器(对我来说非常重要)。现在我知道,在某些情况下,如果函数被解释为它的参数指向的内存块是不重叠的,则可以通过使用关键字来加速函数__restrict__
。
问题:我如何确保编译器知道常量内存中的指针指向的全局内存中的内存块是不重叠的(也许也很高兴知道:在生成随机内核调用之后永远不会改变)?
pointers - 具有受限指针的潜在未定义行为
这里有四个代码片段。为什么保证(或不保证)这段代码会产生明确定义的行为?
受限的“循环引用”:
外向内赋值:
传递给函数:
指针算术循环:
c++ - 有没有一种有效的方法来引用常量实际上是 const 而不是只读的?
让我们看看下面的 C++ 代码:
程序打印:2和3
它清楚地表明,虽然不能修改 A x 类内部,但这仅意味着它是只读的,因为我可以从外部更改它的值。
当然,我可以将它作为存储在 A 类中的副本,但我想知道是否有(或者是否有提议?)对 A 类说成员 x 将是真正的常量,而不仅仅是读取只是,承诺外部代码不会改变它的意思吗?
在我看来,它看起来与 C限制关键字的含义有关,但我还没有听说过任何这样的 C++ 功能。你 ?
c++ - 限制指针类型模板参数和覆盖模板基类的虚拟方法
我相信以下内容应该编译和链接,但不是:
编译器输出:
如果我在两个地方都删除了__restrict__
限定符,它会编译和链接。我究竟做错了什么?
笔记:
- 这是关于限制限定符和模板的唯一问题(截至撰写本文时)。有趣,不是吗?
- 我将 GCC 4.9.3 与
--std=c++11
.
c - 将限制限定的指针传递给函数?
Restrict 限定指针被解释为有一个规则:任何被指针访问并在任何地方修改的对象都只能被指针访问。所以以下不起作用,对吧?
所以,我猜这是无效的,因为 y[n-1] 被修改在某个地方,而不是直接从限制指针 y 访问,并且它被 y 读取。
如果这是正确的,当输入指针是限制条件时,你怎么能调用函数呢?似乎该功能在不违反限制规则的情况下无法执行任何操作。
释放限制指针是否又违反了规定?我猜这是一种修改。
提前致谢!
c - C 限制限定符是可传递的吗?
虽然有很多例子[1] [2] [3]说明了restrict
关键字是如何工作的,但我不完全确定受限关系在它可以指向的指针上是否具有传递性。例如,以下代码声明了一个包含整数和指向整数的指针的结构。
编译器是否需要额外的load
指令来最后访问tmp
(返回值),因为它无法推断*i
并且*tmp
没有别名?
如果是这样,这个新定义会解决这个负载吗?
编辑
当我生成 LLVM IR ( )时,这种情况int bar(container_s *c, int * restrict i) { ... }
会消除提取负载。clang -S -O3 -emit-llvm
但是,我不明白为什么接下来的两个修改在以下情况下不会删除最终负载:
我将函数的定义(是否
/li>restrict
考虑过传递c->i
?)更新为:我更新结构如下(为什么编译器不能推断不需要额外的负载?):
/li>
c - 为什么限制限定符仍然允许 memcpy 访问重叠内存?
我想看看是否restrict
会阻止memcpy
访问重叠的内存。
该memcpy
函数将n个字节从内存区 src直接复制到内存区 dest 。内存区域不应重叠。memmove
使用缓冲区,因此没有重叠内存的风险。
限定符表示在指针的restrict
生命周期内,只有指针本身或直接来自它的值(例如pointer + n
)才能访问该对象的数据。如果不遵循意图声明并且通过独立指针访问对象,这将导致未定义的行为。
输出 ()
自身地址:12345
限制是否停止未定义的行为?
自身地址:12345
停止未定义的 bop 未定义行为?
自身地址:12345
是否memcpy
使用独立指针?因为输出肯定会显示未定义的行为,restrict
并且不会阻止使用memcpy
.
我假设memcpy
它具有性能优势,因为它在memmove
使用缓冲区时直接复制数据。但是对于现代计算机,我是否应该忽略这种潜在的更好性能并始终使用它,memmove
因为它保证没有重叠?
c - 有没有办法告诉 C 编译器指针没有别名存储?
如果 C 编译器知道指针没有别名,它可以执行许多优化。例如,如果我编译以下函数gcc -O2
:
编译器知道读取*p
将始终评估为,x
因此生成的代码等效于为以下函数生成的代码:
但是,如果编译器认为指针可能有别名,则不再执行此优化。例如,如果我们修改f
以便在读取 to 之间调用未知函数*p
,则生成的代码将取消引用p
两次。编译器假定该read_arr
函数可能已经修改了p
指向的值。
在我的特定程序中,当f
函数运行时p
,它持有的指针是唯一写入该arr
数组元素的指针。在这段时间内,代码中的其他函数可能会读取arr
,但不会写入。(他们可能会在完成运行arr
后写入其他值。)f
所以现在我有三个问题:
第一:有没有办法我可以声明我的变量来给 C 编译器这个提示?我尝试添加一个限制注释,p
但生成的代码gcc -O2
与生成的代码相同f_withalias
第二:我在这里使用限制的尝试有效吗?我的理解是,restrict 意味着没有其他指针可以为 p 别名,无论是读取还是写入。但在我的情况下,该read_arr
函数显然也可以访问指向的arr
数组。p
第三:如果上一个问题的答案是“否”,我可以尝试一些不同的东西来代替restrict
吗?
基本上,我需要确保如果我这样做*p = x
,f
那么从arr[17]
. 但是,我希望 GCC 可以随意优化 tox = *p; y = *p
之类的东西x = *p; y = x
,即使两次读取之间存在函数调用。
c - 限制为数组大小的目的是什么?
我明白什么restrict
意思,但我对这种用法/语法有点困惑:
成功编译gcc main.c -Wall -Wextra -Werror -pedantic
在这种情况下,限制如何工作并由编译器解释?
gcc 版本:5.4.0
c++ - 如何在此指针上应用限制限定符
如何将 GCC/Clang 的__restrict__
限定符应用于this
类的指针?
这个问题的灵感来自 Richard Powell 的 CppCon 2018 演讲“ How to Argue(ment) ”。我看到了一个类似的问题“ restrict qualifier on member functions (restrict this pointer)。 ”(所有代码都可以在Compiler Explorer上找到)
上面的代码生成以下程序集。在其中,我们可以看到value
必须通过this
指针加载两次。这是有道理的,这是 C++ 从 C 继承的结果,restrict 限定符允许程序员关闭该行为。我找不到启用指针restrict
功能的方法。this
在Compiler Explorer页面上,我展示了__restrict__
用于省略第二次加载的方法参数的示例。还有一个将结构引用传递给函数并__restrict__
用于省略第二次加载的示例。
我可以想象一个编译器允许程序员this
在方法的参数中提及隐式指针的世界。然后编译器可以允许对this
指针应用限定符。有关示例,请参见下面的代码。
作为一个后续问题,C++ 标准或 C++ 指南中是否有一些东西可以使它this
永远不会有限制限定符?