【问题标题】:What, if any, are the alignment requirements for the atomic intrinsic functions?如果有的话,原子内在函数的对齐要求是什么?
【发布时间】:2015-11-17 09:06:31
【问题描述】:

Delphi 移动目标的原子操作建立在AtomicXXX 内部函数系列之上。 documentation 说:

由于 Delphi 移动编译器不支持内置汇编器,因此 System 单元提供了四个原子内部函数,它们提供了一种原子交换、比较和交换、递增和递减内存值的方法。

这四个功能是:

提供原子操作的其他 RTL 函数,例如TInterlocked 类的静态类方法建立在这四个内在函数之上。

对于面向 ARMv7 的移动编译器,这四个原子内在函数是否有任何对齐要求?如果是这样,它们是什么?

文档没有列出任何此类要求。但是,已知文档不准确,我没有信心将不存在任何规定的要求作为不存在此类要求的明确证据。

顺便说一句,XE8 documentation for intrinsic functions 声明桌面编译器不支持这些原子内在函数。这是不正确的——桌面编译器支持这些内在函数。

【问题讨论】:

    标签: delphi delphi-xe7 armv7


    【解决方案1】:

    XE8 编译

    var 
      a: integer;
    
    AtomicIncrement(a);
    

    3e: 2201        movs    r2, #1
    40: 900c        str r0, [sp, #48]   ; 0x30
    42: 910b        str r1, [sp, #44]   ; 0x2c
    44: 920a        str r2, [sp, #40]   ; 0x28
    46: 980b        ldr r0, [sp, #44]   ; 0x2c
    48: e850 1f00   ldrex   r1, [r0]
    4c: 9a0a        ldr r2, [sp, #40]   ; 0x28
    4e: 4411        add r1, r2
    50: e840 1300   strex   r3, r1, [r0]
    54: 2b00        cmp r3, #0
    56: d1f6        bne.n   46 <_NativeMain+0x46>
    

    所以原子性是使用ldrex/strex实现的。

    如果我正确解释 community.arm.com 处的信息,则所需的对齐方式对于 4 字节操作 (ldrd/strd) 是 DWORD 对齐的,对于 8 字节操作是 QWORD 对齐的。

    其他原子函数以类似的方式实现,因此应适用相同的要求。

    AtomicDecrement(a);
    
    68: 980f        ldr r0, [sp, #60]   ; 0x3c
    6a: e850 1f00   ldrex   r1, [r0]
    6e: 9a0e        ldr r2, [sp, #56]   ; 0x38
    70: 1a89        subs    r1, r1, r2
    72: e840 1300   strex   r3, r1, [r0]
    76: 2b00        cmp r3, #0
    78: d1f6        bne.n   68 <_NativeMain+0x68>
    
    AtomicExchange(a,b);
    
    82: 990f        ldr r1, [sp, #60]   ; 0x3c
    84: 6008        str r0, [r1, #0]
    86: 4873        ldr r0, [pc, #460]  ; (254 <_NativeMain+0x254>)
    88: 9a10        ldr r2, [sp, #64]   ; 0x40
    8a: 5880        ldr r0, [r0, r2]
    8c: 6800        ldr r0, [r0, #0]
    8e: f3bf 8f5b   dmb ish
    92: 900d        str r0, [sp, #52]   ; 0x34
    94: 980f        ldr r0, [sp, #60]   ; 0x3c
    96: e850 1f00   ldrex   r1, [r0]
    9a: 9b0d        ldr r3, [sp, #52]   ; 0x34
    9c: e840 3200   strex   r2, r3, [r0]
    a0: 2a00        cmp r2, #0
    a2: 910c        str r1, [sp, #48]   ; 0x30
    a4: d1f6        bne.n   94 <_NativeMain+0x94>
    
    AtomicCmpExchange(a, 42, 17);
    
    ae: 990f        ldr r1, [sp, #60]   ; 0x3c
    b0: 6008        str r0, [r1, #0]
    b2: f3bf 8f5b   dmb ish
    b6: 202a        movs    r0, #42 ; 0x2a
    b8: 2211        movs    r2, #17
    ba: 900b        str r0, [sp, #44]   ; 0x2c
    bc: 920a        str r2, [sp, #40]   ; 0x28
    be: 980f        ldr r0, [sp, #60]   ; 0x3c
    c0: e850 1f00   ldrex   r1, [r0]
    c4: 9a0a        ldr r2, [sp, #40]   ; 0x28
    c6: 4291        cmp r1, r2
    c8: d105        bne.n   d6 <_NativeMain+0xd6>
    ca: 990b        ldr r1, [sp, #44]   ; 0x2c
    cc: 9a0f        ldr r2, [sp, #60]   ; 0x3c
    ce: e842 1000   strex   r0, r1, [r2]
    d2: 2800        cmp r0, #0
    d4: d1f3        bne.n   be <_NativeMain+0xbe>
    

    【讨论】:

    • LDREX 和 STREX 的对齐要求源于使用专用监视器,而不是 LDR(D)/STR(D) 的通用对齐要求
    【解决方案2】:

    原子性通常使用 LDREX 和 STREX(加载独占/存储独占指令)来实现。这些指令使用一个称为独占监视器的概念。退房: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/ch01s02s01.html 寻找'Exclusives Reservation Granule'

    因此,您的对齐要求是特定于实现的,将由您的硬件上实现的专有监视器机制决定。我建议您查看专用监视器部分的 CPU/SoC 文档。

    例如。 当使用内部监视器并且这些监视器通常在缓存级别(通常是 L2)实现时。每个缓存行都有一个监视器。

    • 因此,您的原子数据应包含在单个缓存行中,对齐将遵循此要求
    • 如果多个原子占用同一个高速缓存行,当一个原子处于独占状态时,同一高速缓存行中的所有其他原子将处于假独占状态。这将导致锁定效率低下。让缓存行对齐的原子可以避免这个问题。 注意:同一缓存行中的多个原子仍然可以工作,但效率低下

    【讨论】:

    • 最后一段的结论是错误的。假设高速缓存行大小是 32 字节。然后你不需要对齐到 32 字节边界。只要数据不大于 32 字节,与数据大小对齐就足够了。例如,4 字节数据可以 4 字节对齐,并且永远不会跨越缓存行。
    • @DavidHeffernan。我所指的对齐问题不是由跨越多个高速缓存行的一个原子数据单元引起的。但问题出在多个原子变量位于同一缓存行中时。当一个原子单元移动到独占状态时,同一缓存行中的不相关原子单元将错误地变为独占(或不公平地锁定以供使用)。因此,出于效率原因,最好让原子由缓存行分隔。 (功能上与 4 字节对齐没有区别)
    • 那是虚假分享的问题,我认为这与这里的问题有些相切
    猜你喜欢
    • 2018-07-29
    • 2015-03-06
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 2020-02-05
    相关资源
    最近更新 更多