我对 restrict 有一般的了解,但我希望澄清一些细节。我有一个函数从一个缓冲区读取一个以null结尾的字符串,并在另一个缓冲区中写出一个URL编码的版本。该函数具有此签名(当前没有 restrict ):

char const *StringUrlEncode(char const *unencoded, 
                            char *encoded,
                            char *encodedEnd);

unncoded 是我的以null结尾的源字符串。目标缓冲区由 encoded encodedEnd 表示,其中 encoded 指向缓冲区中的第一个 char 并且< code> encodedEnd 指向缓冲区后的第一个char ,即该函数将编写 char ,但不包括 encodedEnd 指向的位置 - 如果您熟悉C ++ STL约定,这是您的基本 begin / end 迭代器对。

如果我将 restrict 添加到此函数,它是否应仅应用于前两个参数:

char const *StringUrlEncode(char const *restrict unencoded, 
                            char *restrict encoded,
                            char *encodedEnd);

或者通过将它添加到所有三个参数中,我有什么好处?

我可以看到,输入和输出缓冲区 restrict 有助于编译器知道它们不重叠。但是由于最后一个参数 encodedEnd 仅用于标记输出缓冲区的结尾,我认为 restrict 对编译器没有任何帮助。在这里(虽然我认为它不会伤害,除了在函数声明中添加不必要的噪音)。

有帮助吗?

解决方案

尝试Mike Acton的文章此处。限制是可怕的,因为不使用它的性能影响和不正确使用它的后果。

在你的情况下,听起来你可以安全地对所有三个指针应用restrict,因为没有别名相同的内存区域。但是,在第三个指针上使用它几乎没有性能优势。

其他提示

在这种特殊情况下, encodedEnd 是否受限制无关紧要;你承诺编译器没有人将未编码编码别名,因此读写不会相互干扰。

在这种情况下限制很重要的真正原因是没有它,编译器就不能知道通过编码写入不会影响通过未编码的读取。例如,如果

encoded == unencoded+1

然后每次写入编码都会影响 unncoded 的每次后续读取,因此编译器无法在写入完成之前调度加载。限制承诺编译器,两个指针不会影响相同的内存,因此它可以提前调度负载,以避免管道停滞。

我认为你是对的,它不会受到伤害。你的循环指针(称之为p)将在循环结束时等于encodedEnd。但是在循环之后不需要访问任何东西(来自p或encodedEnd),所以这应该不是问题。我认为它也不会有所帮助,因为没有任何东西可以从encodedEnd写入或读取,因此无法优化。

但我同意你的前两个限制应该真的有帮助。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top