作为我之前question的跟进,atomic类使用memory_order指定大多数操作范围。与栅栏相反,此内存顺序仅影响其操作的原子。据推测,通过使用几个这样的原子,您可以构建一个并发算法,其中其他内存的顺序并不重要。所以我有两个问题:有人能给我指出一个算法/情况的示例,该算法/情况可以从单个原子变量的排序中受益并且不需要需要栅栏吗?哪些现代处理器支持这种行为?也就是说,编译器不会只是将特定顺序转换为正常的围栏。 最佳答案 关于std::atomic操作的内存排序参数变量不会影响该操作本身的顺序,它会影响该操作与其他操作创建的顺
编译器能否对原子指令重新排序,或者原子指令是否充当内存屏障?再说一遍,写在原子指令之后的指令能在原子指令之前执行吗?请看下面的代码。如果useMapA=false在mapB更新和读取线程开始之前移动,我们将使用无效的mapB。注意:更新线程每15分钟才发生一次,因此我们有一个非常好的结构化流程,以及避免使用昂贵的锁定调用的方法!std::atomicuseMapA;std::mapmapA,mapB;publicvoidupdateMap(map*latestMap){if(useMapA){mapB=std::move(*latestMap);useMapA=false;}else{
在VisualC++2013上,当我编译以下代码时#includeintmain(){std::atomicv(2);returnv.fetch_add(1,std::memory_order_relaxed);}我在x86上取回了以下程序集:51pushecxB802000000moveax,28D0C24leaecx,[esp]8701xchgeax,dwordptr[ecx]B801000000moveax,1F00FC101lockxadddwordptr[ecx],eax59popecxC3ret在x64上类似:B802000000moveax,287442408xchgea
我目前正在开展一个项目,其中有一个大型文本文件(15+GB),并且我试图在文件的每一行上运行一个函数。为了加快任务的速度,我创建了4个线程并试图让它们同时读取文件。这与我所拥有的相似:#include#include#include#include#include#includevoidsimpleFunction(*wordlist){stringword;getline(*wordlist,word);coutgetline函数(连同“*wordlist>>word”)似乎分两步递增指针并读取值,正如我经常得到的:Item1Item2Item3Item2返回。所以我想知道是否有一种
std::atomicg_atomic;voidthread0(){intoldVal=0;intnewVal=1;while(g_atomic.compare_exchange_strong(oldVal,newVal,std::memory_order_acq_rel,std::memory_order_acquire)){//forevercountingfrom0to100untilunexpectedvalueappearsoldVal=newVal;newVal=(oldVal+1)%100;};}voidthread1(){//setunexpectedvalueg_at
我在考虑原子变量是否可以加载获取-释放对中的旧值。假设我们有原子变量x,我们用释放语义存储该变量,然后用获取语义加载它,理论上是否可以读取旧值?std::atomicx=0;voidthread_1(){x.store(1,std::memory_order_release);}voidthread_2(){assert(x.load(std::memory_order_acquire)!=0);}如果函数线程1在线程2加载x时完成(因此存储了新值),线程2是否可以从x加载旧值?换句话说,如果对x的实际存储在加载之前完成,断言是否有可能触发?据我从网上的文章中了解到这是可能的,但我不明
假设我们有一个简单的变量(std::atomicvar)和2个线程T1和T2我们有以下代码T1:...var.store(2,mem_order);...和T2...var.load(mem_order)...我们还假设T2(load)执行时间比T1晚123ns(按照C++标准的修改顺序)(店铺)。我对这种情况的理解如下(针对不同的内存顺序):memory_order_seq_cst-T2load有义务加载2.如此有效,它必须加载最新值(就像RMW操作的情况一样)memory_order_acquire/memory_order_release/memory_order_relaxed
为什么GCC和Clang会为此代码(x86_64,-O3-std=c++17)生成如此不同的asm?#includeintglobal_var=0;intfoo_seq_cst(inta){std::atomicia;ia.store(global_var+a,std::memory_order_seq_cst);returnia.load(std::memory_order_seq_cst);}intfoo_relaxed(inta){std::atomicia;ia.store(global_var+a,std::memory_order_relaxed);returnia.loa
我对多线程很感兴趣。该领域有很多陷阱,例如,不能保证指针写入是原子的。我明白了,但想知道在实际情况下最流行的当前配置是什么?例如,在我的MacbookPro/gcc上,指针写入看起来绝对是原子的。 最佳答案 这主要是指针宽度大于CPU架构宽度的CPU架构的问题。例如,在ATmega上CPU,8位架构,地址空间是16位。如果没有任何特定指令来加载和存储16位地址,则至少需要两条指令来加载/存储指针值。 关于c++-指针写入不是原子的最常见配置是什么?,我们在StackOverflow上找到
arrayA;atomic_init(A,{0})和A={ATOMIC_VAR_INIT(0)}似乎都不起作用,返回了一个难以理解的错误。如何将原子数组初始化为0?即使for循环在每一步都更新数组的一个元素也是行不通的。如果我们无法初始化原子数组,它们的用途是什么?我还想补充一点,我的数组的实际大小很大(不是示例中的10),所以我需要直接初始化。 最佳答案 std::array,100>A;for(auto&x:A)std::atomic_init(&x,std::size_t(0));做这个工作使用clang++-std=c++1