原子操作-C [英] Atomic operations - C

查看:126
本文介绍了原子操作-C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使两个变量自动递增.我有以下代码,并且由于它是一个多处理器,多线程的环境,因此缓存失效成为性能瓶颈.因此,我正在尝试减少原子操作的数量.

Is it possible to have two variables incremented atomically. I have the following code and since it's a multi-processor, multi-threaded environment, cache invalidations becomes a performance bottleneck. So, I am trying to minimise the number of atomic operations.

__sync_add_and_fetch(&var1,1);
__sync_add_and_fetch(&var2,1);

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

I see that the first argument is a pointer, is it possible to achieve my case by using a structure?

P.S:我不能使用锁.

P.S: I cannot use locks.

推荐答案

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

Atomic operations are very special and provide only limited support. Applying them to two variables sounds impossible for me.

请注意,甚至不保证原子操作实际上是通过resp完成的.光子操作(即机器代码命令).

Note, that it is even not garanteed that an atomic operation is really done with a resp. actomic operation (i.e. machine code command).

超出gcc文档. 5.47用于原子内存访问的内置函数 :

Out of the gcc doc. 5.47 Built-in functions for atomic memory access:

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

Not all operations are supported by all target processors. If a particular operation cannot be implemented on the target processor, a warning will be generated and a call an external function will be generated. The external function will carry the same name as the builtin, with an additional suffix '_n' where n is the size of the data type.

外部函数可能使用互斥量模拟原子操作.

The external function probably emulates the atomic operation using a mutex.

但是我想,只有在有某些限制的情况下,肮脏的骇客"才有可能:

But I guess, it would be possible with a "dirty hack" and only with certain limitations:

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

If 16 bit unsigned counters are sufficient, you could put two of them in one 32 bit variable where c1c2 += 0x00000001 increments one, c1c2 += 0x00010000 increments the other, and c1c2 += 0x00010001 increments both or using the atomic operations:

/* 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);

这必须与适当的移位和屏蔽结合使用,以访问单个计数器值.

This has to be combined with the appropriate bit shifting and masking to access the invidiual counter values.

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

Of course, counter overflow could be an issue. The same might work for two 32 bit counters on a 64 bit platform (considering that atomic operations are usually only available for "machine word" width).

顺便说一句.在搜寻背景信息时,我偶然发现了以下内容:

Btw. while googling for background info, I stumbled over this: Why does __sync_add_and_fetch work for a 64 bit variable on a 32 bit system?. I found the hint that atomic operations may require sufficient alignment of variables to work properly (which I found worth to mention).

这可能就是为什么 C11原子库为原子变量提供专用类型的原因(例如atomic_uint_least32_t).

This might be the reason why the C11 Atomic Library provides dedicated types for atomic variables (e.g. atomic_uint_least32_t).

这篇关于原子操作-C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆