考虑以下函数。
void incr(_Atomic int *restrict ptr) {
*ptr += 1;
}
我会考虑 x86,但我的问题是关于语言,而不是任何特定原子实现的语义。 GCC 和 Clang 都发出以下内容:
incr:
lock add DWORD PTR [rdi], 1
ret
符合标准的实现是否可以简单地发出
incr:
add DWORD PTR [rdi], 1
ret
(如果您删除 _Atomic
,您会得到同样的结果。)
如果没有 restrict
,这将是一个错误编译,因为 add
不是原子的,所以(例如)同时调用 incr
两个线程会竞争。但是,由于指针是 restrict
限定的,我认为 incr
和任何其他对 *ptr
的访问之间不可能发生竞争(无论如何都不会导致未定义的行为)。
我有信心手动进行此优化,但据我所知,没有编译器会自动进行此操作。这是对的吗?还是我误解了 restrict
?
最佳答案
编译器无法进行优化,因为 restrict
的行为仅针对通过 incr
中的其他指针访问同一对象进行定义.
来自 this reference , 我自己强调:
During each execution of a block in which a restricted pointer P is declared (typically each execution of a function body in which P is a function parameter), if some object that is accessible through P (directly or indirectly) is modified, by any means, then all accesses to that object (both reads and writes) in that block must occur through P (directly or indirectly), otherwise the behavior is undefined...
对指针的限制仅适用于从 incr
进行的访问,这意味着符合标准的编译器不应该能够得出关于其他线程或其他具有指向同一整数的指针的函数的任何访问(这完全没问题 incr
的调用者可能只有不受限制的指向它的指针)。
开放标准第 6.7.3.1 节还定义了 restrict
的正式行为关于正在执行的 block ,不声明任何指针对象的生命周期。但是,我认为该标准的定义在数学上过于笨拙,不值得在这里完整介绍。
关于c - 如果通过限制指针发生,实现是否可以优化对非原子访问的原子访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66695867/