gir*_*cha 5 c concurrency multithreading atomic
是否可以让两个变量以原子方式递增。我有以下代码,由于它是一个多处理器、多线程环境,缓存失效成为性能瓶颈。所以,我试图尽量减少原子操作的数量。
__sync_add_and_fetch(&var1,1);
__sync_add_and_fetch(&var2,1);
Run Code Online (Sandbox Code Playgroud)
我看到第一个参数是一个指针,是否可以通过使用结构来实现我的情况?
PS:我不能使用锁。
原子操作非常特殊,只能提供有限的支持。将它们应用于两个变量对我来说听起来是不可能的。
请注意,甚至不能保证原子操作确实是通过 resp 完成的。原子操作(即机器代码命令)。
出 gcc 文档。5.47 原子内存访问的内置函数:
并非所有目标处理器都支持所有操作。如果无法在目标处理器上执行特定操作,则会生成警告并生成外部函数调用。外部函数将带有与内置函数相同的名称,并带有一个附加后缀“_n”,其中 n 是数据类型的大小。
外部函数可能使用互斥锁模拟原子操作。
但我想,“肮脏的黑客”是可能的,并且只有某些限制:
如果 16 位无符号计数器就足够了,您可以将其中的两个放在一个 32 位变量中,其中c1c2 += 0x00000001一个c1c2 += 0x00010000递增,另一个c1c2 += 0x00010001递增,然后两个递增,或者使用原子操作:
/* 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);
Run Code Online (Sandbox Code Playgroud)
这必须与适当的位移位和屏蔽相结合才能访问各个计数器值。
当然,计数器溢出可能是一个问题。这同样适用于 64 位平台上的两个 32 位计数器(考虑到原子操作通常仅适用于“机器字”宽度)。
顺便提一句。在谷歌搜索背景信息时,我偶然发现了这一点:为什么 __sync_add_and_fetch 在 32 位系统上适用于 64 位变量?. 我发现原子操作可能需要足够的变量对齐才能正常工作的提示(我发现值得一提)。
这可能是C11 原子库为原子变量(例如atomic_uint_least32_t)提供专用类型的原因。
| 归档时间: |
|
| 查看次数: |
12538 次 |
| 最近记录: |