【发布时间】:2016-04-25 19:02:11
【问题描述】:
std::atomic<>compare_exchange() 如何与 MS InterlockedCompareExchange64 在非原子值上相关和转换?是否存在性能或语义差异?
例如,这些代码是否等效?
edit:David Haim 指出应该是int64_t atomic_inc_ms(volatile int64_t& val, int64_t less_than)
int64_t atomic_inc_ms(int64_t& val, int64_t less_than) {
int64_t new_val;
int64_t old_val = val;
while(true)
{
if (old_val > less_than) return old_val;
new_val = old_val + 1;
int64_t got_val = InterlockedCompareExchange64(&val,new_val,old_val);
if(got_val == old_val) break;
old_val = got;
}
return new_val;
}
和
int64_t atomic_inc(std::atomic<int64_t>& val, int64_t less_than) {
int64_t new_val;
int64_t old_val = val.load();
do
{
if (old_val > less_than) return old_val;
new_val = old_val + 1;
} while (!val.compare_exchange_weak(old_val, new_val));
return new_val;
}
一个问题是int64_t old_val = val; 没有明确的原子负载。
这个例子是Is there atomic increment with the check preconditions, that the atomic value was less than the specified value?的例子,和教科书上关于如何使用compare_exchange_weak的例子很接近。
是compare_exchange_weak 和compare_exchange,语义上等价于
InterlockedCompareExchangeAcquire64 和 InterlockedCompareExchange64 ?
【问题讨论】:
-
两者都会编译成同一个东西,又名
lock inc [ptr],所以不用担心。但是您的代码显示了为什么标准更好,您的val不是易失性的,而Interlocked*需要易失性变量。使用atomic时无需考虑。加上盈利能力 -
@DavidHaim。谢谢!我同意 100%。当我评论 SergeyA 的回答时,你打败了我才意识到这一点。我不清楚编译器可以用 val 做什么。
-
@DavidHaim,我理解你的意思吗(我所做的编辑,现在是
volatile int64_t& val)。
标签: c++ multithreading c++11 atomic