原子集的内置 GCC 是啥?
Posted
技术标签:
【中文标题】原子集的内置 GCC 是啥?【英文标题】:What is the GCC builtin for an atomic set?原子集的内置 GCC 是什么? 【发布时间】:2018-04-20 01:56:24 【问题描述】:我在https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html 看到了内置列表。但是对于原子集,您是否需要使用 __sync_lock_test_and_set 和 __sync_lock_release 对?
我在https://attractivechaos.wordpress.com/2011/10/06/multi-threaded-programming-efficiency-of-locking/ 上看到过这个例子。
volatile int lock = 0;
void *worker(void*)
while (__sync_lock_test_and_set(&lock, 1));
// critical section
__sync_lock_release(&lock);
但是如果我使用这个例子,并且在临界区中做我的原子集,那么不同变量的原子集将被不必要地序列化。
感谢任何关于如何在我有多个原子变量的情况下进行原子集的输入。
【问题讨论】:
你真的必须使用那些遗留的内置函数吗? gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/… 建议在新代码中避免使用它们。 好主意。我在“c 中的原子操作”中找到的大多数链接都是关于这些遗留内置函数的。 __atomic_store 内置函数可以实现我的 atomic64_set 函数。 【参考方案1】:根据定义需要同时使用两者
__sync_synchronize (...)
这个内置函数发出一个完整的内存屏障。输入
__sync_lock_test_and_set (type *ptr, type value, ...)
正如英特尔所描述的,这个内置不是传统的测试和设置 操作,而是原子交换操作。它写入值 进入 *ptr,并返回 *ptr 之前的内容。许多目标 对这种锁只有最低限度的支持,不支持完整的 交换操作。在这种情况下,目标可能支持减少 此处唯一要存储的有效值是 立即常数 1. 实际存储在 *ptr 中的确切值是 实现定义。
这个内置不是一个完整的屏障,而是一个获取屏障。 这意味着内置函数之后的引用不能移动到(或 推测)在内置之前,但以前的内存存储可能不会 仍然是全局可见的,并且以前的内存负载可能还不是 使满意。
void __sync_lock_release (type *ptr, ...)
这个内置释放 由 __sync_lock_test_and_set 获取的锁。通常这意味着写 常数 0 到 *ptr。这个内置不是一个完整的障碍,而是 释放屏障。这意味着所有以前的内存存储都是 全局可见,并且所有先前的内存负载都已得到满足, 但不会阻止以下内存读取被推测为 在障碍之前。
【讨论】:
你知道是否有一个单独的调用来设置一个值吗?由于 GCC 提供了 __sync_fetch_and_or() 之类的操作,因此似乎应该有一个 __sync_set 操作。如果没有,你能否提供一个如何做的例子。使用 __sync_synchronize()。它有相应的发布调用吗?在我能找到的几个例子中没有看到一个。谢谢!【参考方案2】:我想出了这个解决方案。如果您知道更好的请回复:
typedef struct
volatile int lock; // must be initialized to 0 before 1st call to atomic64_set
volatile long long counter;
atomic64_t;
static inline void atomic64_set(atomic64_t *v, long long i)
// see https://attractivechaos.wordpress.com/2011/10/06/multi-threaded-programming-efficiency-of-locking/
// for an explanation of __sync_lock_test_and_set
while (__sync_lock_test_and_set(&v->lock, 1)) // we don't have the lock, so busy wait until
while (v->lock); // it is released (i.e. lock is set to 0)
// by the holder via __sync_lock_release()
// critical section
v->counter = i;
__sync_lock_release(&v->lock);
【讨论】:
以上是关于原子集的内置 GCC 是啥?的主要内容,如果未能解决你的问题,请参考以下文章