squ*_*rem 5 arm transactional-memory memory-model arm64 intel-tsx
ARM 事务内存扩展对如何使用它们有相当简单的描述:
sem_post:
TSTART X0 // Start of outer transaction
CBNZ test_fail // No reason for this routine to cancel or fail
LDR X1, [X2] // X2 points to semaphore
ADD X1, X1, #1 // Increment semaphore value
STR X1, [X2]. // Store incremented value
TCOMMIT // Commit transaction and exit
Run Code Online (Sandbox Code Playgroud)
我想要弄清楚的是,这些事务是否基于与代码其他部分中的事务的冲突而重放,以及它们是否基于与任何类型的访问的冲突而重放。为了详细说明,假设我们有这个例程:
sem_wait:
TSTART X0 // Start of outer transaction
CBNZ retry_check // This routine checks for retry (RTRY) and restarts transaction
LDR X1, [X2] // X2 points to semaphore
CMP X1, #0 // Check if semaphore is already used
CBNZ decrement // If it's non-zero, we can decrement the semaphore
TCANCEL #0xFF // If it's zero, we gotta retry
decrement:
SUB X1, X1, #1 // Decrement semaphore value
STR X1, [X2]. // Store decremented value
TCOMMIT // Commit transaction and exit
Run Code Online (Sandbox Code Playgroud)
因此,该事务将位于代码的另一部分,但将作为 sem_post 事务访问内存中的位置。
我的第一个问题:执行事务的线程sem_post
可能会重播并发执行sem_wait
事务的线程吗?
对于我的问题的第二部分,假设我们有一个像这样的简单例程:
break_semaphore:
MOV X0, #0xFF
STR X0, [X1] // X1 points to semaphore
Run Code Online (Sandbox Code Playgroud)
上面的例程根本不是事务,它只是搞乱了信号量。
我的第二个问题:执行sem_post
事务的线程是否可能由于对事务中要更新和提交的位置的任何并发访问sem_post
而重放?
为了清楚起见,我完全理解这并不是 TME 指令真正应该使用的方式,并且锁的实现方式更像是这样的:https ://www.gem5.org/project/2020/10/27/ tme.html
我更想知道事务实际上线性化的是什么:具有公共代码区域的两个事务、所有彼此之间的事务,或者相对于所有其他内存访问的事务?
小智 2
TME 确实线性化了对共享内存区域的访问。在您的示例中,这些事务中止的原因不是因为它们正在执行相同的代码,而是因为共享内存地址。
根据ARM TME 文档,内存地址的任何冲突状态都会导致 TSTART 失败并设置 MEM 位。在信号量示例的上下文中,由于没有用于调用的回退代码sem_post
,事务将取消程序执行状态将恢复到非事务状态。
出于类似的原因,事务不一定通过执行相同的代码来线性化,因为它们可能引用不同的内存区域(即具有不同指针的多个信号量),这是完全合法的。
事务之间是否线性化更难回答,因为它通常依赖于硬件。例如,两个事务可以在具有不同内存对象的不同核心上合法执行,但如果两个事务尝试在同一核心和寄存器上执行(即,使用超线程),则这种行为将更难以定义。
归档时间: |
|
查看次数: |
368 次 |
最近记录: |