Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在没有内存障碍的情况下实现联锁增量_C_Multithreading_Interlocked - Fatal编程技术网

C 如何在没有内存障碍的情况下实现联锁增量

C 如何在没有内存障碍的情况下实现联锁增量,c,multithreading,interlocked,C,Multithreading,Interlocked,我实现了一个引用计数模式,为此我需要联锁设施,但没有内存围栏(据我所知) 不幸的是,只有Windows具有InterlocatedDecrementNofence编译器内部。 如何使用asm内联实现这一点?对于gcc/clang,我也需要它。对于这个操作的语义来说,缺少至少一个内在的内存围栏操作(取决于平台)几乎是不可能的。为了使原子递增/递减有效,另一个处理器必须在对变量执行自己的操作之前确保看到原子操作的值,并且变量操作的可见性必须具有某种保证的总顺序。内存障碍,甚至是隐含的障碍,例如在x8

我实现了一个引用计数模式,为此我需要联锁设施,但没有内存围栏(据我所知)

不幸的是,只有Windows具有InterlocatedDecrementNofence编译器内部。
如何使用asm内联实现这一点?对于gcc/clang,我也需要它。

对于这个操作的语义来说,缺少至少一个内在的内存围栏操作(取决于平台)几乎是不可能的。为了使原子递增/递减有效,另一个处理器必须在对变量执行自己的操作之前确保看到原子操作的值,并且变量操作的可见性必须具有某种保证的总顺序。内存障碍,甚至是隐含的障碍,例如在x86这样的强内存模型中,标准内存操作具有获取/释放语义,对于原子递增/递减操作的正确性至关重要


请记住,即使MSVC/gcc的文档说明存在内存障碍,由于平台的强内存模型,x86上也不会应用实际的内存障碍(即
MFENCE
指令),而是在内存总线上锁定以确保操作的原子性。另一方面,由于该平台的内存模型较弱,IA64将需要一个内存屏障。ARM也是如此。

这不是一个直接的答案,而是一个替代方案。如果您可以使用C11(或C++11),那么使用
内存\u顺序\u松弛的原子操作如何?在弱内存模型平台上,编译器可能不会生成内存限制。(取决于编译器供应商/版本)

#包括
原子内变量;
国际奥德瓦尔;
oldval=atomic\u fetch\u sub\u explicit(&var,1,内存\u顺序\u松弛);

Um。。。不管怎样,MSVC和gcc中的内联程序集将不同。。。障碍物更好地保存在它所属的地方。所以我确实误解了障碍的概念。因为我认为它只会影响挂起的不同读/写操作的顺序。对于refcounting,根本不存在排序问题,因为只涉及一个内存位置。在多处理器系统中,缓存一致性协议已经解决了这个问题。。。根据平台的不同,可能没有明确的内存屏障操作,但您仍然要像支付惩罚一样支付惩罚,因为您必须使原子操作的结果对所有其他处理器可见,并且每个原子操作必须对给定的内存地址具有总顺序。
#include <stdatomic.h>

atomic_int var;
int oldval;

oldval = atomic_fetch_sub_explicit(&var, 1, memory_order_relaxed);