加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

多线程 – 何时使用测试和设置或测试和测试?

发布时间:2020-12-15 08:36:43 所属栏目:Java 来源:网络整理
导读:x86下的并行编程可能很难,尤其是在多核CPU下. 假设我们有多核x86 CPU和更多不同的多线程通信组合. 单一作家和单一读者 单读者多个作家 多个读者和单个作家 多个读者和多个作家 那么哪一个模型更好(更有效)来锁定共享内存区域:测试和设置或测试测试和设置以
x86下的并行编程可能很难,尤其是在多核CPU下.
假设我们有多核x86 CPU和更多不同的多线程通信组合.

>单一作家和单一读者
>单读者多个作家
>多个读者和单个作家
>多个读者和多个作家

那么哪一个模型更好(更有效)来锁定共享内存区域:测试和设置或测试&测试和设置以及何时使用它!

这里我有两个简单(没有时间限制)的测试程序,用x86汇编程序在Delphi IDE下编写:

procedure TestAndSet(const oldValue,newValue: cardinal; var destination);
asm
//eax = oldValue
//edx = NewLockValue
//ecx = destination = 32 bit pointer on lock variable 4 byte aligned
@RepeatSpinLoop:
        push    eax                   //Save lock oldValue (compared)
        pause                         //CPU spin-loop hint
        lock    cmpxchg dword ptr [ecx],edx
        pop     eax                   //Restore eax as oldValue
        jnz     @RepeatSpinLoop       //Repeat if cmpxchg wasn't successful
end;

procedure TestAndTestAndSet(const oldValue,newValue: cardinal; var destination);
asm
//eax = oldValue
//edx = NewLockValue
//ecx = destination = 32 bit pointer on lock variable 4 byte aligned
@RepeatSpinLoop:
        push    eax                   //Save lock oldValue (compared)
@SpinLoop:
        pause                         //CPU spin-loop hint
        cmp     dword ptr [ecx],eax  //Test betfore test&set
        jnz     @SpinLoop
        lock    cmpxchg dword ptr [ecx],edx
        pop     eax                   //Restore eax as oldValue
        jnz     @RepeatSpinLoop       //Repeat if cmpxchg wasn't successful
end;

编辑:

英特尔在文档中提到了两种方法Test& Set或Test& Test& Set.我不会在哪种情况下建立更好的方法,所以何时使用它.检查:Intel

解决方法

TTAS(#2)是一种很好的做法.在潜在CAS之前“潜伏”并等待“机会”是Java和.NET并发类中的常见做法.有了这个说法,cmpxchg在过去几年中得到了很多优化,所以你可能会在最新的处理器上获得几乎相同的结果.

在这两种情况下你应该尝试的是,当你旋转时使用一些exponential backoff.

更新

@GJ:你应该找到some more up-to-date documentation on Intel’s site.注意自486以来没有锁定总线的段落以及xchg和cmpxchg的对比图表明它们实际上是相同的.

在读取与锁定指令上旋转仍然是一个好主意,以避免在独占模式下获取高速缓存行时的一些争用. (所以TTAS.)

然而,只有在您实施例如,这将提供有用的增益.指数后退,甚至在一段时间后产生CPU.

如果您使用单个现代多核CPU,并且核心之间具有共享L3缓存,那么TTAS和TAS之间的差异,或者无退避将会更小,如果您使用的是多插槽,则会更加明显 – 例如服务器 – 机器或核心之间没有共享缓存的多核CPU.根据争用的数量,它们也会有所不同. (即轻载会看到TTAS / TAS之间的差异较小.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读