【问题标题】:InterlockedCompareExchange64 vs std::atomic compare_exchangeInterlockedCompareExchange64 与 std::atomic compare_exchange
【发布时间】: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_weakcompare_exchange,语义上等价于 InterlockedCompareExchangeAcquire64InterlockedCompareExchange64 ?

【问题讨论】:

  • 两者都会编译成同一个东西,又名lock inc [ptr],所以不用担心。但是您的代码显示了为什么标准更好,您的 val 不是易失性的,而 Interlocked* 需要易失性变量。使用atomic 时无需考虑。加上盈利能力
  • @DavidHaim。谢谢!我同意 100%。当我评论 SergeyA 的回答时,你打败了我才意识到这一点。我不清楚编译器可以用 val 做什么。
  • @DavidHaim,我理解你的意思吗(我所做的编辑,现在是volatile int64_t&amp; val)。

标签: c++ multithreading c++11 atomic


【解决方案1】:

这些代码在语义上是等价的。 int64_t 的原子负载在这里无关紧要,因为 Interlocked* 系列函数提示 X86,其中所有负载都是原子的。

c++ atomics 有可能比Interlocked* 函数运行得稍快,因为编译器将生成直接 ASM 调用而不是调用函数。但是,编译器也可能会识别Interlocked* 函数。

【讨论】:

  • 好的。伟大的!而且,我的代码'int64_t old_val = val;'。不需要 volatile 或其他可以从其他线程更改 val 的标记?也许volatile int64_t&amp; val
【解决方案2】:

std::atomic 是 C++ 标准。它是可移植的代码,可以使用任何兼容的编译器进行编译

Interlocked* 是 Windows SDK 中特定于 Windows 的功能。因此,该代码将不可移植。

【讨论】:

  • 谢谢。这是真的,但没有回答我关于语义的任何问题。
  • AFAIK 这些差异可能太小而无法衡量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
相关资源
最近更新 更多