首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >原子操作--C

原子操作--C
EN

Stack Overflow用户
提问于 2017-06-22 14:07:40
回答 2查看 13.9K关注 0票数 5

有没有可能让两个变量自动递增。我有以下代码,因为它是一个多处理器、多线程的环境,缓存失效成为性能瓶颈。因此,我正在尝试最小化原子操作的数量。

代码语言:javascript
复制
__sync_add_and_fetch(&var1,1);
__sync_add_and_fetch(&var2,1);

我看到第一个参数是一个指针,是否可以通过使用结构来实现我的情况?

附言:我不能使用锁。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-22 14:52:27

原子操作非常特殊,只提供有限的支持。将它们应用于两个变量对我来说是不可能的。

请注意,甚至不能保证原子操作是真正使用resp完成的。执行操作(即机器代码命令)。

走出了gcc的博士。5.47 Built-in functions for atomic memory access

并非所有目标处理器都支持所有操作。如果某个特定的操作无法在目标处理器上实现,则会生成一个警告,并生成一个调用外部函数的消息。外部函数将带有与内置函数相同的名称,并附加一个后缀'_n‘,其中n是数据类型的大小。

外部函数可能使用互斥锁来模拟原子操作。

但我猜,使用“肮脏的黑客”是可能的,而且只有一定的限制:

如果16位无符号计数器足够,您可以将其中两个放入一个32位变量中,其中c1c2 += 0x00000001递增一个,c1c2 += 0x00010000递增另一个,c1c2 += 0x00010001同时递增两个,或者使用原子操作:

代码语言:javascript
复制
/* combined counters c1 and c2 */
static uint32_t c1c2 = 0;

/* count c1 atomically */
__sync_fetch_and_add(&c1c2, 0x00000001);
/* count c2 atomically */
__sync_fetch_and_add(&c1c2, 0x00010000);
/* count c1 AND c2 atomically */
__sync_fetch_and_add(&c1c2, 0x00010001);

这必须与适当的位移位和掩码相结合,以访问初始计数器值。

当然,计数器溢出可能是一个问题。这同样适用于64位平台上的两个32位计数器(考虑到原子操作通常仅适用于“机器字”宽度)。

顺便说一句。在谷歌搜索背景信息时,我偶然发现了这个:Why does __sync_add_and_fetch work for a 64 bit variable on a 32 bit system?。我发现原子操作可能需要充分的变量对齐才能正常工作(这一点值得一提的是)。

这可能是C11 Atomic Library为原子变量(例如atomic_uint_least32_t)提供专用类型的原因。

票数 6
EN

Stack Overflow用户

发布于 2020-04-14 20:10:56

除了两个奔腾处理器(类似于2001年的AMD处理器)之外,所有的奔腾处理器都支持128位原子操作。这是16个字节。

在C++中可以通过atomic<>模板实现对这些操作的支持,尽管最近的一个GCC版本对16字节值关闭了这一功能,并使用了锁。但是,各个编译器都有访问这些代码的方法,原则上也可以用机器语言编写。

操作的范围是有限的,但原则上您可以在常规C中做任何想做的事情,然后用CAS操作用新内容替换现有内容。CAS的意思就是: CPU,当且仅当B当前持有值C时,将值A写入内存位置B。因此:读取值;进行计算;然后使用CAS并在成功时使用CAS成功代码中断do..while循环。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44691392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档