std :: atomic将一对原子int32视为一个原子int64? [英] std::atomic treat a pair of atomic int32 as one atomic int64?

查看:135
本文介绍了std :: atomic将一对原子int32视为一个原子int64?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一对未签名的int32

  std :: atomic< u32> _开始; 
std :: atomic< u32> _结束;

有时候我想设置比较交换的开始或结束,所以我不希望出现虚假的失败可能是由于在整个64位对上使用CAS引起的。我只想使用32位CAS。

  _end.compare_exchange_strong(old_end,new_end); 

现在,我可以读取64个原子的开始和结束。或两个单独的32位读取。

$ b进行一次64位原子获取(通过编译器添加适当的内存隔离栅)比用两个内存隔离栅进行两个单独的32个原子位读取要快(还是编译器会对此进行优化?)


$ b

如果是这样,我将如何在c ++ 11中做到这一点?

解决方案

标准不保证 std :: atomics 具有与基础类型相同的大小,也不保证 atomic 上的操作是无锁的(尽管它们至少可能用于 uint32 )。因此,我很确定没有任何合规的方法可以将它们组合成一个 64bit 原子操作。因此,您需要确定是否要手动将这两个变量合并为一个64位变量(并且仅适用于64位操作)。



例如,该平台可能不支持 64bit CAS(对于第一个奔腾IIRC添加的x86,因此在编译486兼容版本时将不可用,这种情况下它需要以某种方式锁定,因此原子可能同时包含 64bit 变量和锁定。 >

关于围栏:这取决于您为操作指定的 memory_order 如果内存顺序指定了这两个操作如果需要按执行顺序显示它们,显然编译器将无法优化隔离,否则可能会。当然,假设您仅针对x86 memory_order_seq_cst 根据我的记忆,实际上会发出一个屏障指令,因此,其他任何事情都将阻碍编译器对指令的重新排序,但不会造成实际的损失。)



当然取决于您的平台,您可能无法处理两个 std :: atomi c< int32> 作为 int64 之一通过 union reinterpret_cast ,只需告知该行为不是标准要求的,并且可以(至少在理论上)随时停止工作(新的编译器版本,不同的优化设置,...)


I have a pair of unsigned int32

std::atomic<u32> _start;
std::atomic<u32> _end;

Sometimes I want to set start or end with compare exchange, so I don't want spurious failures that could be caused by using CAS on the entire 64bit pair. I just want to use 32 bit CAS.

_end.compare_exchange_strong(old_end, new_end);

Now I could fetch both start and end as one atomic 64bit read. Or two separate 32 bit reads. Wouldn't it be faster to do one 64bit atomic fetch (with the compiler adding the appropriate memory fence) rather than two separate 32 atomic bit reads with two memory fences (or would the compiler optimize that away?)

If so, how would I do that in c++11?

解决方案

The standard doesn't guarantee that std::atomics have the same size as the underlying type, nor that the operations on atomic are lockfree (although they are likely to be for uint32 at least). Therefore I'm pretty sure there isn't any conforming way to combine them into one 64bit atomic operation. So you need to decide whether you want to manually combine the two variables into a 64bit one (and only work with 64bit operations) or not.

As an example the platform might not support 64bit CAS (for x86 that was added with the first Pentium IIRC, so it would not be availible when compiling 486 compatible. In that case it needs to lock somehow, so the atomic might contain both the 64bit variable and the lock. Of

Concerning the fences: Well that depends on the memory_order you specify for your operation. If the memory order specifies that the two operations need to be visible in the order they are excuted in, the compiler will obviously not be able to optimize a fence away, otherwise it might. Of course assuming you target x86 only memory_order_seq_cst will actually emit a barrierinstruction from what I remember, so anything less would impede with instruction reordering done by the compiler, but wouldn't have an actual penalty).

Of course depending on your platform you might get away with treating two std::atomic<int32> as one of int64 doing the casting either via union or reinterpret_cast, just be advised that this behaviour is not required by the standard and can (at least theoretically) stop working at anytime (new compiler verison, different optimization settings,...)

这篇关于std :: atomic将一对原子int32视为一个原子int64?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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