【问题标题】:Adding a synchronization point in x86 assembly在 x86 程序集中添加同步点
【发布时间】:2013-08-10 11:50:45
【问题描述】:

我必须有办法让四个线程从某个点大致同时运行。例如

thread 1 : mov eax,ebx, mov ecx, edx, [S], mov eax, edx, ...
thread 2:  sbb eax,ebx, [S], mov ecx, edx, ...
thread 3:  mov eax,ebx, xchg eax,ebx, cmp edx, ecx, [S], mov eax, ebx, ...
thread 4:  dec eax, sub eax,ecx, [S], ....

[S] 是“同步点”的占位符。在所有线程都达到这一点后,它们应该大致同时启动。我该怎么做?

我的代码类似于

number_of_threads 4

temp:
      dd 0            ;a 'synchronization variable'

线程 1 代码

;synchronization [S]

lock add [temp],0x1
wloop1:                 
cmp [temp], number_of_threads 
jne wloop1

线程 2 代码

;synchronization [S]

lock add [temp],0x1
wloop2:                 
cmp [temp], number_of_threads 
jne wloop2

线程 3 代码

;synchronization [S]

lock add [temp],0x1
wloop3:                 
cmp [temp], number_of_threads 
jne wloop3

线程 4 代码

;synchronization [S]

lock add [temp],0x1
wloop4:                 
cmp [temp], number_of_threads 
jne wloop4

通过这种方式,我们确保所有线程都到达 [S] 并大致同时从那里开始。 [S] 后面的代码只有在 temp 变为 number_of_threads 时才会执行 这段代码是否存在诸如race之类的问题?我什至不确定这是否是这样做的方法。

【问题讨论】:

    标签: multithreading x86


    【解决方案1】:

    这是一种方法,我没有看到竞争条件。但是,它肯定会因为忙于等待而占用您的线程。如果预计等待时间很短,这还不错,但是对于超过一毫秒左右的等待时间,您确实应该使用操作系统提供的同步原语。在等待时旋转该循环会像糖果一样消耗 CPU 周期,如果这些等待时间很长,您会注意到性能问题。

    在 Windows 上,您可以使用 Synchronization Barrier。 Linux 世界中可能有类似的东西。我不能肯定,因为我对 Linux 编程不太熟悉。

    您可能对 x86 暂停指令感兴趣,它可以减少 CPU 负载。 This answer 有很好的描述。

    【讨论】:

    • +1。不过,我会提出这样的观点,即一秒钟太长了,不能坐在自旋锁中(平均而言)。一到两毫秒应该是标准 - 否则应该使用更高级别的同步原语。
    • @Jim Mischel Synchronization Barrier 绝对是一个起点,问题是我没有操作系统。我正在尝试单独在汇编中实现这一点。
    • @500-InternalServerError:已更正。谢谢。
    • @JimMischel 谢谢,所以看起来在 CMP 之前有一个 PAUSE 指令是最简单的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多